Android 開發中用到的幾個多線程解析

Android 開發中用到的幾個多線程解析

在開發工程中線程能夠幫助咱們提升運行速度,Android開發中我知道的線程有四個一個是老生長談的Thread,第二個是asyncTask,第三個:TimetTask,第四個是Looper,四個多線程各有個的有點,Thread的運行速度是最快的,AsyncTask的規範性是最棒的,其它兩個也有本身的優勢,下面先貼上三個列子 java

1.Thread與Handler組合,比較常見 android

Handler主要是幫助咱們來時時更新UI線程 多線程

這裏在後天加載100張圖片,而後沒加載完成一個用handler 返回給UI線程一張圖片並顯示 app

最後加載完成返回一個List給UI線程 ,Handler就是一個後臺線程與UI線程中間的橋樑 異步

package com.android.wei.thread; async

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List; ide

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; oop

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);
    }
} this

 

2AsyncTask異步多線程 spa

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);    } }

相關文章
相關標籤/搜索