Android中采用Handle进行消息传递,本文从实例出发分析Handle中一个Message从创建到处理整个流程,以此阐明消息传递机制原理。
一、Handle使用示例
1、在Android studio 创建一个默认项目,在MainActivity中写下如下代码:
public class MainActivity extends AppCompatActivity {
private TextView tv;
private final static int MSGTYPE =1;
//主线程中创建Handle,并重写Handle处理消息的方法handleMessage()
//我这里只是简单处理更新一个textview显示
Handler mHandle = new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case MSGTYPE:
if(tv !=null){
tv.setText(String.valueOf(msg.obj));
Log.d("Handle",String.valueOf(msg.obj));
}
break;
}
super.handleMessage(msg);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
new Thread(){
@Override
public void run() {
try {
for(int i= 0 ; i<10; i++) {
Thread.sleep(1000);
//耗时操作在子线程完成,建立一个消息
//实体,并携带数据
Message msg = new Message();
msg.what = MSGTYPE;
msg.obj = "Thread" + i;
//通过Handle发送消息
mHandle.sendMessage(msg);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
}
}
子线程通过handle发消息给主线程(UI线程)然后在主线程handle中处理消息,来达到更新UI目的。那么问题来了在这里我们为什么不直接在主线程更新UI或者直接在子线程调用tv.setText()?不在主线程更新是因为主线程不能进行耗时操作,假设一种场景tv控件的数据来源于网络,需要建立一个http获取数据,网络操作是一种极其耗时操作,要等几秒才能更新UI,这对用户体验来说极其不好,而且Android规定UI线程5s没反应,会报ANR错误,所以耗时操作都放子线程。而由于主线程不是线程安全的,Android规定子线程不能更新UI元素。
二、Handle原理分析
在这里我们从上述demo中mHandle.sendMessage(msg)这句代码作为切入口,分析这个msg经过哪些流程被送到mHandle.handleMessage(msg)中进行处理的。
进入Handle.java
//Handler构造函数
public Handler() {
//调用下面含有2个参数的构造函数
this(null, false);