在開發工程中線程可以協助我們提高運行速度,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); }}
2. AsyncTask非同步多線程
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(); }@Overrideprotected 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){//時時拿到當前的進度更新UIBundle 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);}}
3. TimerTask
可以根據我們的設定來間隔性的運行,可以很好的實現監聽功能一般也跟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(){@Overridepublic 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); }}