
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方法。
代码演示:
- package com.example.handlertest;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ProgressBar;
- /**
- * Handler的演示操作,演示Handler的运行机制
- * */
- public class HandlerActivity extends Activity {
- //进度条
- private ProgressBar pb_handler = null;
- //开始按钮
- private Button btn_start = null;
- //结束按钮
- private Button btn_end = null;
- private final static String TAG = "TEST";
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- pb_handler = (ProgressBar)findViewById(R.id.pb_handler);
- btn_start = (Button)findViewById(R.id.btn_start);
- Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());
- btn_start.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //将要执行的Runnable对象添加到消息队列中
- handler.post(runtestHandler);
- }
- });
- btn_end = (Button)findViewById(R.id.btn_end);
- btn_end.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //将正在执行的Runnable对象从消息队列移除
- handler.removeCallbacks(runtestHandler);
- }
- });
- }
- private int i = 0;
- private Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- //接收Runnable操作中发过来的消息信息,改变进度条的长度
- pb_handler.setProgress(msg.arg1);
- }
- };
- private Runnable runtestHandler = new Runnable() {
- @Override
- public void run() {
- i += 5;
- Log.i(TAG, "Handler所在线程ID为 "+Thread.currentThread().getId());
- Log.i(TAG, "数字="+i);
- //得到一个消息
- Message msg = handler.obtainMessage();
- //给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少
- msg.arg1 = i;
- //发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象
- handler.sendMessage(msg);
- handler.postDelayed(runtestHandler, 1000);
- }
- };
- }
2. HandlerThread操作
Handler类既然不是新开了一个线程,必然一些操作如大数据或网络下载操作之类的就不能仅仅用Handler,针对这种情况,出现了HandlerThread类,该类用于方便的创建一个含有looper的线程类,通过此类实现多线程操作。注意:looper用来创建handler类。并且必须调用start()方法。
将上面的demo修改为HandlerThread 多线程,演示Demo如下:
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.HandlerThread;
- import android.os.Looper;
- import android.os.Message;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ProgressBar;
- /**
- * HandlerThread的演示操作
- * 演示HandlerThread与Handler配合使用,实现多线程的运行机制
- * 同时包含Message各种消息形式的演示
- * */
- public class HandlerThreadActivity extends Activity {
- //进度条
- private ProgressBar pb_handler = null;
- //开始按钮
- private Button btn_start = null;
- //结束按钮
- private Button btn_end = null;
- private final static String TAG = "TEST";
- private HandlerThread handlerThead = null;
- private ProgressBarHandler handler = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- pb_handler = (ProgressBar)findViewById(R.id.pb_handler);
- btn_start = (Button)findViewById(R.id.btn_start);
- Log.i(TAG, "UI主线程ID为 "+Thread.currentThread().getId());
- //new一个handlerThead对象
- handlerThead = new HandlerThread("handlerThead");
- //必须调用
- handlerThead.start();
- btn_start.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- handler = new ProgressBarHandler(handlerThead.getLooper());
- //将要执行的Runnable对象添加到消息队列中
- handler.post(runtestHandler);
- }
- });
- btn_end = (Button)findViewById(R.id.btn_end);
- btn_end.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //将正在执行的Runnable对象从消息队列移除
- handler.removeCallbacks(runtestHandler);
- }
- });
- }
- private int i = 0;
- /**
- * 内部类,用于Looper与Handler配合实现多线程操作,Looper轮训机制
- * */
- class ProgressBarHandler extends Handler{
- public ProgressBarHandler(){
- }
- public ProgressBarHandler(Looper looper){
- super(looper);
- }
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- //接收Runnable操作中发过来的消息信息,改变进度条的长度
- pb_handler.setProgress(msg.arg1);
- //接收推送过来的消息中的Bundle信息
- Bundle bundle = msg.getData();
- Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str0"));
- Log.i(TAG, "Message通过Bundle传过来的内容:"+bundle.getString("str1"));
- switch(msg.what){//接收自定义的消息值
- case R.id.btn_end:{//此处仅是测试,下面这段代码会让进度条停止,进度条只前进一次
- handler.removeCallbacks(runtestHandler);
- Log.i(TAG, "此处是接收自定义消息信息");
- }
- }
- }
- };
- private Runnable runtestHandler = new Runnable() {
- @Override
- public void run() {
- i += 5;
- Log.i(TAG, "采用HandlerThread后Handler所在线程ID为 "+Thread.currentThread().getId());
- Log.i(TAG, "数字="+i);
- //得到一个消息
- Message msg = handler.obtainMessage();
- //给消息赋值,arg1与arg2主要是一些简单的int数据,优点是消耗的资源少
- msg.arg1 = i;
- //创建一个Bundle对象
- Bundle bundle = new Bundle();
- bundle.putString("str0", "data 1");
- bundle.putString("str1", "data 2");
- msg.setData(bundle);
- //msg.what自定义的消息值,这个东东在开发中经常使用
- msg.what = R.id.btn_end;
- //发送消息,自动将消息赋值给Handler对象对应的HandlerMessage中Message对象
- msg.sendToTarget();
- handler.postDelayed(runtestHandler, 1000);
- }
- };
- }
总结,通过学习HandlerThread与Handler,可以方便的操作一些多线程,便于UI界面等友好性设计。
备注:以上学习来自mars老师的教学视频和android sdk一些资料,欢迎大家查看。