2025-05-23

在開發工程中線程可以幫助我們提高運行速度,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
}
 

摘自  antkingwei
 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *