前几天发博客说要看源码写博客,今天终于要开张了;第一个专题是Android异步消息处理机制,虽然平时经常用到Handler,用法也比较简单,但是看完源码之后,发现里面还是有很多知识点的^_^
1.概述
Handler在平常开发中经常使用到,用来在不同组件(这里的组件不是Android里的组件,可以理解为代码块,类,线程,进程都可以)之间进行消息传递;
本专题会分以下几篇(暂定两篇)来详细描述:
源码是Android4.0.3版本的;
2.用法
在平常使用中,接触到的类有Message,Handler,Looper,在使用中最重要的类是Handler;关于Hanlder的介绍,在源码注释中
有这么一段描述
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the
future; and (2) to enqueue an action to be performed on a different thread than your own.
大概意思就是Handler有两个用处,一是序列化Message和Runnable对象,以便在将来的某个时间点进行处理;二是在不同线程之间发送消息;
其实在某些跨进程场景下,也可以使用Handler(Handler里Messager对象就是用来跨进程消息接收)
下面将介绍前两种用法,第三种(跨进程消息传递)暂不介绍,在后续的Binder专题中会专门介绍;
1)序列化Message和Runnable
public class TestActivity extends Activity implements View.OnClickListener {
private static final int MSG_CLICK_ONE = 1;
private static final int MSG_CLICK_TWO = 2;
private MyHandler mHandler = new MyHandler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
findViewById(R.id.tv_click_one).setOnClickListener(this);
findViewById(R.id.tv_click_two).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_click_one:
mHandler.sendEmptyMessage(MSG_CLICK_ONE);
break;
case R.id.tv_click_two:
mHandler.sendEmptyMessage(MSG_CLICK_TWO);
break;
}
}
private static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CLICK_ONE:
Log.e("Test", "click one");
break;
case MSG_CLICK_TWO:
Log.e("Test", "click two");
break;
default:
break;
}
super.handleMessage(msg);
}
}
}
上面就是最简单的代码块之间的消息传递,上面提到Message和Runnable的序列化,其实Runnable最终也是生成Message对象进入消息队列的;
2)线程之间消息传递
public class TestActivity extends Activity implements View.OnClickListener {
private static final int MSG_CLICK = 1;
private Handler mHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
findViewById(R.id.tv_click).setOnClickListener(this);
MyThread thread = new MyThread();
thread.start();
mHandler = thread.getHandler();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.tv_click:
mHandler.sendEmptyMessage(MSG_CLICK);
break;
default:
break;
}
}
private static class MyThread extends Thread {
private MyHandler mHandler;
@Override
public void run() {
//初始化子线程的Looper和MessageQueue
Looper.prepare();
mHandler = new MyHandler();
//消息队列进入循环执行
Looper.loop();
}
public Handler getHandler() {
return mHandler;
}
}
private static class MyHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CLICK:
Log.e("Test", "click");
break;
default:
break;
}
super.handleMessage(msg);
}
}
}
需要注意的是,主线程(UI线程)在启动的时候会自己生成Looper和MessageQ,但是子线程是没有,所以在子线程执行的时候要先初始化Looper和MessageQueue对象,之后才能使用消息队列进行消息接收和处理;