您的位置:首页 > 移动开发 > Android开发

Android 多线程操作之 Handler 与 HandlerThread

2013-01-21 15:04 453 查看
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方法。

代码演示:

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一些资料,欢迎大家查看。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: