Android 开发中用到的几个多线程解析

Android 开发中用到的几个多线程解析

在开发工程中线程可以帮助我们提高运行速度,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);
    }
}

 

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只能被执行一次,否则多次调用时将会出现异常

 

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

 

转载于:https://my.oschina.net/u/1035715/blog/156251

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值