Android 開發中用到的幾個多線程解析(程式碼範例)

來源:互聯網
上載者:User

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.