当前位置: 代码迷 >> Android >> Android开发顶用到的几种多线程
  详细解决方案

Android开发顶用到的几种多线程

热度:98   发布时间:2016-05-01 20:03:02.0
Android开发中用到的几种多线程

在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各有个的有点,Thread的运行速度是最快的,AsyncTask的规范性是最棒的,其它两个也有自己的优点,下面先贴上三个列子

1.Thread与Handler组合,比较常见

Handler主要是帮助我们来时时更新UI线程

这里在后天加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示

最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁

?

package com.android.wei.thread;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;public class Activity01 extends Activity {    /** Called when the activity is first created. */      /**读取进度**/    public final static int LOAD_PROGRESS =0;        /**标志读取进度结束**/    public final static int LOAD_COMPLETE = 1;    /**开始加载100张图片按钮**/    Button mButton = null;        /**显示内容**/    TextView mTextView = null;        /**加载图片前的时间**/    Long mLoadStart = 0L;    /**加载图片完成的时间**/    Long mLoadEndt = 0L;        Context mContext = null;    /**图片列表**/    private List<Bitmap> list;    /**图片容器**/    private ImageView mImageView;    //接受传过来得消息    Handler handler = new Handler(){    	public void handleMessage(Message msg){    		switch(msg.what){    		case LOAD_PROGRESS:    			Bitmap bitmap = (Bitmap)msg.obj;    			mTextView.setText("当前读取到第"+msg.arg1+"张图片");    			mImageView.setImageBitmap(bitmap);    			break;    		case LOAD_COMPLETE:	    			list = (List<Bitmap>) msg.obj;    			mTextView.setText("读取结束一共加载"+list.size()+"图片");    			break;    		}    		super.handleMessage(msg);    	}    };    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        mContext = this;        setContentView(R.layout.main);        mButton =(Button) findViewById(R.id.button1);        mTextView=(TextView) findViewById(R.id.textView1);        mImageView =(ImageView) this.findViewById(R.id.imageview);        mTextView.setText("点击按钮加载图片");        mButton.setOnClickListener(new OnClickListener(){        	public void onClick(View v){        		//调用方法        		LoadImage();        	}        });        	            }    public void LoadImage(){    	new Thread(){    		public void run(){    			mLoadStart = System.currentTimeMillis();    			List<Bitmap> list = new ArrayList<Bitmap>();    			for(int i =0;i<100;i++){    				Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon);    				Message msg = new Message();    				msg.what = LOAD_PROGRESS;    				msg.arg1 = i+1;    				list.add(bitmap);    				msg.obj = bitmap;    				handler.sendMessage(msg);    			}    			mLoadEndt = System.currentTimeMillis();    			Message msg = new Message();    			msg.what = LOAD_COMPLETE;    			msg.obj=list;    			msg.arg1 = (int) (mLoadEndt - mLoadStart);    			handler.sendMessage(msg);    			    		}    	}.start();    }    public Bitmap ReadBitmap(Context context,int resId){    	BitmapFactory.Options opt = new BitmapFactory.Options();    	opt.inPreferredConfig = Bitmap.Config.RGB_565;    	opt.inPurgeable = true;    	opt.inInputShareable = true;    	InputStream is = context.getResources().openRawResource(resId);    	return BitmapFactory.decodeStream(is, null, opt);    }}

?

2AsyncTask异步多线程

?

AsyncTask的规范型很强,能够时时反映更新的情况

它一般有这么几个方法

?

?* onPreExecute(), 该方法将在执行实际的后台操作前被UI 线程调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条,或者一些控件的实例化,这个方法可以不用实现。
????? ?* doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台处理工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
????? * onProgressUpdate(Progress...),在publishProgress方法被调用后,UI 线程将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
????? * onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI 线程调用,后台的计算结果将通过该方法传递到UI 线程,并且在界面上展示给用户.

????? * onCancelled(),在用户取消线程操作的时候调用。在主线程中调用onCancelled()的时候调用。

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:

??? 1) Task的实例必须在UI 线程中创建

??? 2) execute方法必须在UI 线程中调用

??? 3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法,需要在UI线程中实例化这个task来调用。

??? 4) 该task只能被执行一次,否则多次调用时将会出现异常

?

package com.android.wei.thread;import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;import android.widget.TextView;public class Activity02 extends Activity{		/**开始StartAsync按钮**/	Button mButton = null;		Context mContext = null;		//内容显示出来	TextView mTextView = null;		//Timer 对象	Timer mTimer = null;		/** timerTask 对象**/	TimerTask mTimerTask = null;		/**记录TimerId**/	int mTimerId =0;	/**图片列表**/	private List<Bitmap> list;	/**图片容器**/	private ImageView mImageView;	public void onCreate(Bundle s){		super.onCreate(s);		setContentView(R.layout.main);		mContext = this;		mButton =(Button) this.findViewById(R.id.button1);		mImageView =(ImageView)this.findViewById(R.id.imageview);		mTextView =(TextView) this.findViewById(R.id.textView1);		mButton.setOnClickListener(new OnClickListener(){			public void onClick(View v){				StartAsync();			}		});					}	public void StartAsync(){		new AsyncTask<Object,Object,Object>(){            protected void onPreExecute(){            	//首先执行这个方法,它在UI线程中,可以执行一些异步操作            	mTextView.setText("开始加载进度");            	super.onPreExecute();            }			@Override			protected Object doInBackground(Object... params) {				// TODO Auto-generated method stub				//异步后台执行,执行完毕可以返回出去一个结果 Object 对象				//得到开始加载得时间				list = new ArrayList<Bitmap>();				for(int i =0;i<100;i++){					Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon);										final ByteArrayOutputStream os = new ByteArrayOutputStream();					bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);					byte[] image = os.toByteArray();					Bundle bundle = new Bundle();					bundle.putInt("index", i);					bundle.putByteArray("image", image);					publishProgress(bundle);					list.add(bitmap);									}								return list;			}			protected void onPostExecute(Object result){				//doInBackground 执行之后在这里可以接受到返回结果的对象				List<Bitmap> list = (List<Bitmap>) result;				mTextView.setText("一共加载了"+list.size()+"张图片");			   super.onPostExecute(result);			}			protected void onProgressUpdate(Object... values){				//时时拿到当前的进度更新UI				Bundle bundle = (Bundle)values[0];				byte[] image = bundle.getByteArray("image");				Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);				int index = bundle.getInt("index");				mTextView.setText("当前加载进度"+index);				mImageView.setImageBitmap(bitmap);				super.onProgressUpdate(values);			}					}.execute();	}	public Bitmap ReadBitmap(Context context,int resId){		BitmapFactory.Options opt = new BitmapFactory.Options();		opt.inPreferredConfig = Bitmap.Config.RGB_565;		opt.inPurgeable = true;		opt.inInputShareable = true;		InputStream is = context.getResources().openRawResource(resId);		return BitmapFactory.decodeStream(is, null, opt);	}	}

?

3TimerTask

?

可以根据我们的设置来间隔性的运行,可以很好的实现监听功能一般也跟handler一起

?

package com.android.wei.thread;import java.util.Timer;import java.util.TimerTask;import android.app.Activity;import android.content.Context;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class TimerTaskActivity extends Activity{	/**执行Timer进度**/	public final static int LOAD_PROGRESS =0;		/**关闭TImer进度**/	public final static int CLOSE_PROGRESS =1;		/**开始TIMERTASK按钮**/	Button mButton0 = null;		/**关闭TIMERTASK按钮**/	Button mButton1 =null;		/**显示内容**/	TextView mTextView = null;		Context mContext = null;		/**timer对象**/	Timer mTimer = null;		/**TimerTask对象**/	TimerTask mTimerTask = null;		/**记录TimerID**/	int mTimerID =0;		Handler handler = new Handler(){		public void handleMessage(Message msg){			switch(msg.what){			case LOAD_PROGRESS:				mTextView.setText("当前得TimerID为:"+msg.arg1);				break;			case CLOSE_PROGRESS:				mTextView.setText("当前Timer已经关闭请重新启动");				break;			}			super.handleMessage(msg);		}	};    protected void onCreate(Bundle s){    	setContentView(R.layout.timer);    	mContext  = this;    	mButton0 = (Button) this.findViewById(R.id.button1);    	mButton1 = (Button) this.findViewById(R.id.button2);    	mTextView = (TextView) this.findViewById(R.id.textView1);    	mTextView.setText("点击按钮开始更新时间");    	mButton0.setOnClickListener(new OnClickListener(){    		public void onClick(View v){    			StartTimer();    		}    	});    	mButton1.setOnClickListener(new OnClickListener(){    		public void onClick(View v){    			CloseTimer();    		}    	});    	super.onCreate(s);    }   public void StartTimer(){	    if(mTimer == null){	    	mTimerTask = new TimerTask(){				@Override				public void run() {					mTimerID ++;					Message msg = new Message();					msg.what = LOAD_PROGRESS;					msg.arg1 =(int) (mTimerID);					handler.sendMessage(msg);									}				    			    	};	    	mTimer = new Timer();	    	//第一个参数为执行的mTimerTask	    	//第二个参数为延迟得事件,这里写1000得意思是 mTimerTask将延迟1秒执行	    	//第三个参数为多久执行一次,这里写1000 表示没1秒执行一次mTimerTask的Run方法	    	mTimer.schedule(mTimerTask, 1000,1000);	    }   }   public void CloseTimer(){	   if(mTimer !=null){		   mTimer.cancel();		   mTimer = null;	   }	   if(mTimerTask!= null){		   mTimerTask = null;	   }	   mTimerID =0;	   handler.sendEmptyMessage(CLOSE_PROGRESS);   }}

?

  相关解决方案