Android 多线程操作之 Handler 与 HandlerThread

来源:互联网 发布:three.js视频教程下载 编辑:程序博客网 时间:2024/05/16 00:44
1.  Handler操作微笑

 

Handler主要用于执行消息队列的传送与runnable线程;消息队列用于多线程。注:Handler操作实际与UI主线程是一个线程,虽然主要操作在Runnable中,但是其实它与UI主线程是一个线程。

1)   创建一个Handler对象:Handler handler = new Handler();

2)   调用Handler对象的post方法,将要执行的对象添加到队列中:handler.post(runnable线程);

3)   将要执行的操作写在线程对象run方法中:

privateRunnable runnable = new Runnable(){

              public void run(){

                     //相关业务操作

}

}

4)   若要循环执行操作,可在run()方法中执行handler对象的postDelayed方法。

 

 

代码演示:

 

[java] view plaincopy
  1. package com.example.handlertest;  
  2.   
  3. import android.app.Activity;  
  4. import android.os.Bundle;  
  5. import android.os.Handler;  
  6. import android.os.Message;  
  7. import android.util.Log;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. import android.widget.ProgressBar;  
  12. /** 
  13.  * Handler的演示操作,演示Handler的运行机制 
  14.  * */  
  15. public class HandlerActivity extends Activity {  
  16.   
  17.     //进度条  
  18.     private ProgressBar pb_handler = null;  
  19.     //开始按钮  
  20.     private Button btn_start = null;  
  21.     //结束按钮  
  22.     private Button btn_end = null;  
  23.       
  24.     private final static String TAG = "TEST";  
  25.     @Override  
  26.     protected void onCreate(Bundle savedInstanceState) {  
  27.         super.onCreate(savedInstanceState);  
  28.         setContentView(R.layout.activity_main);  
  29.         pb_handler = (ProgressBar)findViewById(R.id.pb_handler);  
  30.         btn_start = (Button)findViewById(R.id.btn_start);  
  31.         Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());  
  32.         btn_start.setOnClickListener(new OnClickListener() {  
  33.               
  34.             @Override  
  35.             public void onClick(View v) {  
  36.                 //将要执行的Runnable对象添加到消息队列中  
  37.                 handler.post(runtestHandler);  
  38.             }  
  39.         });  
  40.         btn_end = (Button)findViewById(R.id.btn_end);  
  41.         btn_end.setOnClickListener(new OnClickListener() {  
  42.               
  43.             @Override  
  44.             public void onClick(View v) {  
  45.                 //将正在执行的Runnable对象从消息队列移除  
  46.                 handler.removeCallbacks(runtestHandler);  
  47.             }  
  48.         });  
  49.           
  50.     }  
  51.     private int i = 0;  
  52.     private Handler handler = new Handler(){  
  53.         @Override  
  54.         public void handleMessage(Message msg) {  
  55.             super.handleMessage(msg);  
  56.             //接收Runnable操作中发过来的消息信息,改变进度条的长度  
  57.             pb_handler.setProgress(msg.arg1);  
  58.         }  
  59.     };  
  60.     private Runnable runtestHandler = new Runnable() {  
  61.           
  62.         @Override  
  63.         public void run() {  
  64.             i += 5;  
  65.             Log.i(TAG, "Handler所在线程ID为 "+Thread.currentThread().getId());  
  66.             Log.i(TAG, "数字="+i);  
  67.             //得到一个消息  
  68.             Message msg = handler.obtainMessage();  
  69.             //给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少  
  70.             msg.arg1 = i;  
  71.             //发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象  
  72.             handler.sendMessage(msg);  
  73.             handler.postDelayed(runtestHandler, 1000);  
  74.         }  
  75.     };  
  76. }  

 

2.   HandlerThread操作        微笑

          Handler类既然不是新开了一个线程,必然一些操作如大数据或网络下载操作之类的就不能仅仅用Handler,针对这种情况,出现了HandlerThread类,该类用于方便的创建一个含有looper的线程类,通过此类实现多线程操作。注意:looper用来创建handler类。并且必须调用start()方法。

        将上面的demo修改为HandlerThread 多线程,演示Demo如下:

[java] view plaincopy
  1. import android.app.Activity;  
  2. import android.os.Bundle;  
  3. import android.os.Handler;  
  4. import android.os.HandlerThread;  
  5. import android.os.Looper;  
  6. import android.os.Message;  
  7. import android.util.Log;  
  8. import android.view.View;  
  9. import android.view.View.OnClickListener;  
  10. import android.widget.Button;  
  11. import android.widget.ProgressBar;  
  12. /** 
  13.  * HandlerThread的演示操作 
  14.  * 演示HandlerThread与Handler配合使用,实现多线程的运行机制 
  15.  * 同时包含Message各种消息形式的演示 
  16.  * */  
  17. public class HandlerThreadActivity extends Activity {  
  18.   
  19.     //进度条  
  20.     private ProgressBar pb_handler = null;  
  21.     //开始按钮  
  22.     private Button btn_start = null;  
  23.     //结束按钮  
  24.     private Button btn_end = null;  
  25.       
  26.     private final static String TAG = "TEST";  
  27.       
  28.     private HandlerThread handlerThead = null;  
  29.     private ProgressBarHandler handler = null;  
  30.       
  31.     @Override  
  32.     protected void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         setContentView(R.layout.activity_main);  
  35.         pb_handler = (ProgressBar)findViewById(R.id.pb_handler);  
  36.         btn_start = (Button)findViewById(R.id.btn_start);  
  37.         Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());  
  38.         //new一个handlerThead对象  
  39.         handlerThead = new HandlerThread("handlerThead");  
  40.         //必须调用  
  41.         handlerThead.start();  
  42.           
  43.           
  44.         btn_start.setOnClickListener(new OnClickListener() {  
  45.               
  46.             @Override  
  47.             public void onClick(View v) {  
  48.                   
  49.                 handler = new ProgressBarHandler(handlerThead.getLooper());  
  50.                 //将要执行的Runnable对象添加到消息队列中  
  51.                 handler.post(runtestHandler);  
  52.                   
  53.             }  
  54.         });  
  55.         btn_end = (Button)findViewById(R.id.btn_end);  
  56.         btn_end.setOnClickListener(new OnClickListener() {  
  57.               
  58.             @Override  
  59.             public void onClick(View v) {  
  60.                 //将正在执行的Runnable对象从消息队列移除  
  61.                 handler.removeCallbacks(runtestHandler);  
  62.             }  
  63.         });  
  64.           
  65.           
  66.     }  
  67.     private int i = 0;  
  68.       
  69.     /** 
  70.      * 内部类,用于Looper与Handler配合实现多线程操作,Looper轮训机制 
  71.      * */  
  72.     class ProgressBarHandler extends Handler{  
  73.           
  74.         public ProgressBarHandler(){  
  75.               
  76.         }  
  77.           
  78.         public ProgressBarHandler(Looper looper){  
  79.             super(looper);  
  80.         }  
  81.           
  82.         @Override  
  83.         public void handleMessage(Message msg) {  
  84.             super.handleMessage(msg);  
  85.             //接收Runnable操作中发过来的消息信息,改变进度条的长度  
  86.             pb_handler.setProgress(msg.arg1);  
  87.             //接收推送过来的消息中的Bundle信息  
  88.             Bundle bundle = msg.getData();  
  89.             Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str0"));  
  90.             Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str1"));  
  91.             switch(msg.what){//接收自定义的消息值  
  92.                 case R.id.btn_end:{//此处仅是测试,下面这段代码会让进度条停止,进度条只前进一次  
  93.                     handler.removeCallbacks(runtestHandler);  
  94.                     Log.i(TAG, "此处是接收自定义消息信息");  
  95.                 }  
  96.             }  
  97.         }  
  98.     };  
  99.     private Runnable runtestHandler = new Runnable() {  
  100.           
  101.   
  102.         @Override  
  103.         public void run() {  
  104.             i += 5;  
  105.             Log.i(TAG, "采用HandlerThread后Handler所在线程ID为 "+Thread.currentThread().getId());  
  106.             Log.i(TAG, "数字="+i);  
  107.             //得到一个消息  
  108.             Message msg = handler.obtainMessage();  
  109.             //给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少  
  110.             msg.arg1 = i;  
  111.             //创建一个Bundle对象  
  112.             Bundle bundle = new Bundle();  
  113.             bundle.putString("str0""data 1");  
  114.             bundle.putString("str1""data 2");  
  115.             msg.setData(bundle);  
  116.             //msg.what自定义的消息值,这个东东在开发中经常使用  
  117.             msg.what = R.id.btn_end;  
  118.             //发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象  
  119.             msg.sendToTarget();  
  120.             handler.postDelayed(runtestHandler, 1000);  
  121.         }  
  122.     };  
  123. }  

 微笑微笑微笑微笑微笑

总结,通过学习HandlerThread与Handler,可以方便的操作一些多线程,便于UI界面等友好性设计。

微笑微笑微笑微笑微笑

备注:以上学习来自mars老师的教学视频和android sdk一些资料,欢迎大家查看。

0 0