Android 开发中用到的几个多线程解析
2894 点击·0 回帖
![]() | ![]() | |
![]() | 在开发工程中线程可以帮助我们提高运行速度,Android开发中我知道的线程有四个一个是老生长谈的Thread,第二个是asyncTask,第三个:TimetTask,第四个是Looper,四个多线程各有个的有点,Thread的运行速度是最快的,AsyncTask的规范性是最棒的,其它两个也有自己的优点,下面先贴上三个列子 1.Thread与Handler组合,比较常见 Handler主要是帮助我们来时时更新UI线程 这里在后天加载100张图片,然后没加载完成一个用handler 返回给UI线程一张图片并显示 最后加载完成返回一个List给UI线程 ,Handler就是一个后台线程与UI线程中间的桥梁 001 package com.Android.wei.thread; 002 003 import java.io.InputStream; 004 import java.util.ArrayList; 005 import java.util.List; 006 007 import Android.app.Activity; 008 import Android.content.Context; 009 import Android.graphics.Bitmap; 010 import Android.graphics.BitmapFactory; 011 import Android.os.Bundle; 012 import Android.os.Handler; 013 import Android.os.Message; 014 import Android.view.View; 015 import Android.view.View.OnClickListener; 016 import Android.widget.Button; 017 import Android.widget.ImageView; 018 import Android.widget.TextView; 019 020 public class Activity01 extends Activity { 021 /** Called when the activity is first created. */ 022 023 /**读取进度**/ 024 public final static int LOAD_PROGRESS =0; 025 026 /**标志读取进度结束**/ 027 public final static int LOAD_COMPLETE = 1; 028 /**开始加载100张图片按钮**/ 029 Button mButton = null; 030 031 /**显示内容**/ 032 TextView mTextView = null; 033 034 /**加载图片前的时间**/ 035 Long mLoadStart = 0L; 036 /**加载图片完成的时间**/ 037 Long mLoadEndt = 0L; 038 039 Context mContext = null; 040 /**图片列表**/ 041 private List<Bitmap> list; 042 /**图片容器**/ 043 private ImageView mImageView; 044 //接受传过来得消息 045 Handler handler = new Handler(){ 046 public void handleMessage(Message msg){ 047 switch(msg.what){ 048 case LOAD_PROGRESS: 049 Bitmap bitmap = (Bitmap)msg.obj; 050 mTextView.setText("当前读取到第"+msg.arg1+"张图片"); 051 mImageView.setImageBitmap(bitmap); 052 break; 053 case LOAD_COMPLETE: 054 list = (List<Bitmap>) msg.obj; 055 mTextView.setText("读取结束一共加载"+list.size()+"图片"); 056 break; 057 } 058 super.handleMessage(msg); 059 } 060 }; 061 public void onCreate(Bundle savedInstanceState) { 062 super.onCreate(savedInstanceState); 063 mContext = this; 064 setContentView(R.layout.main); 065 mButton =(Button) findViewById(R.id.button1); 066 mTextView=(TextView) findViewById(R.id.textView1); 067 mImageView =(ImageView) this.findViewById(R.id.imageview); 068 mTextView.setText("点击按钮加载图片"); 069 mButton.setOnClickListener(new OnClickListener(){ 070 public void onClick(View v){ 071 //调用方法 072 LoadImage(); 073 } 074 }); 075 076 077 } 078 public void LoadImage(){ 079 new Thread(){ 080 public void run(){ 081 mLoadStart = System.currentTimeMillis(); 082 List<Bitmap> list = new ArrayList<Bitmap>(); 083 for(int i =0;i<100;i++){ 084 Bitmap bitmap=ReadBitmap(mContext,R.drawable.icon); 085 Message msg = new Message(); 086 msg.what = LOAD_PROGRESS; 087 msg.arg1 = i+1; 088 list.add(bitmap); 089 msg.obj = bitmap; 090 handler.sendMessage(msg); 091 } 092 mLoadEndt = System.currentTimeMillis(); 093 Message msg = new Message(); 094 msg.what = LOAD_COMPLETE; 095 msg.obj=list; 096 msg.arg1 = (int) (mLoadEndt - mLoadStart); 097 handler.sendMessage(msg); 098 099 } 100 }.start(); 101 } 102 public Bitmap ReadBitmap(Context context,int resId){ 103 BitmapFactory.Options opt = new BitmapFactory.Options(); 104 opt.inPreferredConfig = Bitmap.Config.RGB_565; 105 opt.inPurgeable = true; 106 opt.inInputShareable = true; 107 InputStream is = context.getResources().openRawResource(resId); 108 return BitmapFactory.decodeStream(is, null, opt); 109 } 110 } 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只能被执行一次,否则多次调用时将会出现异常 001 package com.Android.wei.thread; 002 003 import java.io.ByteArrayOutputStream; 004 import java.io.InputStream; 005 import java.util.ArrayList; 006 import java.util.List; 007 import java.util.Timer; 008 import java.util.TimerTask; 009 010 import Android.app.Activity; 011 import Android.content.Context; 012 import Android.graphics.Bitmap; 013 import Android.graphics.BitmapFactory; 014 import Android.os.AsyncTask; 015 import Android.os.Bundle; 016 import Android.view.View; 017 import Android.view.View.OnClickListener; 018 import Android.widget.Button; 019 import Android.widget.ImageView; 020 import Android.widget.TextView; 021 022 public class Activity02 extends Activity{ 023 024 /**开始StartAsync按钮**/ 025 Button mButton = null; 026 027 Context mContext = null; 028 029 //内容显示出来 030 TextView mTextView = null; 031 032 //Timer 对象 033 Timer mTimer = null; 034 035 /** timerTask 对象**/ 036 TimerTask mTimerTask = null; 037 038 /**记录TimerId**/ 039 int mTimerId =0; 040 /**图片列表**/ 041 private List<Bitmap> list; 042 /**图片容器**/ 043 private ImageView mImageView; 044 public void onCreate(Bundle s){ 045 super.onCreate(s); 046 setContentView(R.layout.main); 047 mContext = this; 048 mButton =(Button) this.findViewById(R.id.button1); 049 mImageView =(ImageView)this.findViewById(R.id.imageview); 050 mTextView =(TextView) this.findViewById(R.id.textView1); 051 mButton.setOnClickListener(new OnClickListener(){ 052 public void onClick(View v){ 053 StartAsync(); 054 } 055 }); 056 057 058 } 059 public void StartAsync(){ 060 new AsyncTask<Object,Object,Object>(){ 061 protected void onPreExecute(){ 062 //首先执行这个方法,它在UI线程中,可以执行一些异步操作 063 mTextView.setText("开始加载进度"); 064 super.onPreExecute(); 065 } 066 @Override 067 protected Object doInBackground(Object... params) { 068 // TODO Auto-generated method stub 069 //异步后台执行,执行完毕可以返回出去一个结果 Object 对象 070 //得到开始加载得时间 071 list = new ArrayList<Bitmap>(); 072 for(int i =0;i<100;i++){ 073 Bitmap bitmap =ReadBitmap(mContext,R.drawable.icon); 074 final ByteArrayOutputStream os = new ByteArrayOutputStream(); 075 bitmap.compress(Bitmap.CompressFormat.PNG, 100, os); 076 byte[] image = os.toByteArray(); 077 Bundle bundle = new Bundle(); 078 bundle.putInt("index", i); 079 bundle.putByteArray("image", image); 080 publishProgress(bundle); 081 list.add(bitmap); 082 083 } 084 085 return list; 086 } 087 protected void onPostExecute(Object result){ 088 //doInBackground 执行之后在这里可以接受到返回结果的对象 089 List<Bitmap> list = (List<Bitmap>) result; 090 mTextView.setText("一共加载了"+list.size()+"张图片"); 091 super.onPostExecute(result); 092 } 093 protected void onProgressUpdate(Object... values){ 094 //时时拿到当前的进度更新UI 095 Bundle bundle = (Bundle)values[0]; 096 byte[] image = bundle.getByteArray("image"); 097 Bitmap bitmap = BitmapFactory.decodeByteArray(image, 0, image.length); 098 int index = bundle.getInt("index"); 099 mTextView.setText("当前加载进度"+index); 100 mImageView.setImageBitmap(bitmap); 101 super.onProgressUpdate(values); 102 } 103 104 }.execute(); 105 } 106 public Bitmap ReadBitmap(Context context,int resId){ 107 BitmapFactory.Options opt = new BitmapFactory.Options(); 108 opt.inPreferredConfig = Bitmap.Config.RGB_565; 109 opt.inPurgeable = true; 110 opt.inInputShareable = true; 111 InputStream is = context.getResources().openRawResource(resId); 112 return BitmapFactory.decodeStream(is, null, opt); 113 } 114 115 } 3TimerTask 可以根据我们的设置来间隔性的运行,可以很好的实现监听功能一般也跟handler一起 001 package com.Android.wei.thread; 002 003 import java.util.Timer; 004 import java.util.TimerTask; 005 006 import Android.app.Activity; 007 import Android.content.Context; 008 import Android.os.Bundle; 009 import Android.os.Handler; 010 import Android.os.Message; 011 import Android.view.View; 012 import Android.view.View.OnClickListener; 013 import Android.widget.Button; 014 import Android.widget.TextView; 015 016 public class TimerTaskActivity extends Activity{ 017 /**执行Timer进度**/ 018 public final static int LOAD_PROGRESS =0; 019 020 /**关闭TImer进度**/ 021 public final static int CLOSE_PROGRESS =1; 022 023 /**开始TIMERTASK按钮**/ 024 Button mButton0 = null; 025 026 /**关闭TIMERTASK按钮**/ 027 Button mButton1 =null; 028 029 /**显示内容**/ 030 TextView mTextView = null; 031 032 Context mContext = null; 033 034 /**timer对象**/ 035 Timer mTimer = null; 036 037 /**TimerTask对象**/ 038 TimerTask mTimerTask = null; 039 040 /**记录TimerID**/ 041 int mTimerID =0; 042 043 Handler handler = new Handler(){ 044 public void handleMessage(Message msg){ 045 switch(msg.what){ 046 case LOAD_PROGRESS: 047 mTextView.setText("当前得TimerID为:"+msg.arg1); 048 break; 049 case CLOSE_PROGRESS: 050 mTextView.setText("当前Timer已经关闭请重新启动"); 051 break; 052 } 053 super.handleMessage(msg); 054 } 055 }; 056 protected void onCreate(Bundle s){ 057 setContentView(R.layout.timer); 058 mContext = this; 059 mButton0 = (Button) this.findViewById(R.id.button1); 060 mButton1 = (Button) this.findViewById(R.id.button2); 061 mTextView = (TextView) this.findViewById(R.id.textView1); 062 mTextView.setText("点击按钮开始更新时间"); 063 mButton0.setOnClickListener(new OnClickListener(){ 064 public void onClick(View v){ 065 StartTimer(); 066 } 067 }); 068 mButton1.setOnClickListener(new OnClickListener(){ 069 public void onClick(View v){ 070 CloseTimer(); 071 } 072 }); 073 super.onCreate(s); 074 } 075 public void StartTimer(){ 076 if(mTimer == null){ 077 mTimerTask = new TimerTask(){ 078 079 @Override 080 public void run() { 081 mTimerID ++; 082 Message msg = new Message(); 083 msg.what = LOAD_PROGRESS; 084 msg.arg1 =(int) (mTimerID); 085 handler.sendMessage(msg); 086 087 } 088 089 }; 090 mTimer = new Timer(); 091 //第一个参数为执行的mTimerTask 092 //第二个参数为延迟得事件,这里写1000得意思是 mTimerTask将延迟1秒执行 093 //第三个参数为多久执行一次,这里写1000 表示没1秒执行一次mTimerTask的Run方法 094 mTimer.schedule(mTimerTask, 1000,1000); 095 } 096 } 097 public void CloseTimer(){ 098 if(mTimer !=null){ 099 mTimer.cancel(); 100 mTimer = null; 101 } 102 if(mTimerTask!= null){ 103 mTimerTask = null; 104 } 105 mTimerID =0; 106 handler.sendEmptyMessage(CLOSE_PROGRESS); 107 } 108 } | |
![]() | ![]() |