关于Android的消息分发机制,我一直弄不清里面Handler,Message,Looper,MessageQueue之间的关系,从上手Android开发接触到这个问题,一直处于懵懂状态,只会按部就班的使用,至于为什么这样用,为什么总时出现Looper.prepare(),Looper.loop(),post(),obtain()这些字眼,也知道他们具体是干什么的,就是不知道为什么那样用。总之就是不能从大局着手,所以不能对他们有一个全局的认识,因此导致只会使用。最近由于项目中使用到消息分发机制,又一次查资料,奋战了好一段时间终于弄懂了,现在把我的理解分享给大家,如果不恰当的地方希望大家能够及时指出。
说白了消息机制解决的问题无非是以下几个:
1,怎么创建消息
2,创建的消息后怎么发送出去,
3,待发送的消息最终要发送到那里去,
4,在哪里取出消息,怎么取出消息
5,取出消息之后怎么处理这条消息
目前我的理解就是这几条,如果把这几条困惑梳理清楚了,那么消息机制也就理解到差不多了;二话不说先上代码,这个Demo实现的主要功能就是点击按钮改变TextView里面的内容。
public class MainActivity extends AppCompatActivity {
private Handler handler;
private TextView textView;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.textView);
button=findViewById(R.id.button);
//新开一个线程用来处理消息,但是在new Handler()之前需要新建一个looper对象
new Thread(new Runnable() {
@Override
public void run() {
//使用prepare()方法用来新建一个线程
Looper.prepare();
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case 1:
textView.setText("yly");
break;
}
}
};
//looper()方法必须写上,为的是使得消息循环起来
Looper.loop();
}
}).start();
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//新建另外一个线程,用于发送需要处理的消息
new Thread(new Runnable() {
@Override
public void run() {
Message message=Message.obtain();
message.what=1;
handler.sendMessage(message);
}
}).start();
}
});
}
}
内容并不是很发杂,下面我们一条一条加以解析。
1,怎么创建消息?首先我们在button的点击事件中开启了一个线程,通过Message.obtain()这个方法来获取创建消息,当然也可以使用Message msg=new Message()来创建消息,至于两者之间有什么区别自己去查找相关资料。
2,创建的消息之后怎么发送出去?在这里我们使用handler.sendMessge()这个方法把消息发送出去。当然handler必须要提前实例化才能使用,实例化handler是在另外一个线程中进行的,实例化Handler之前我们必须要有Looper对象,所以必须使用prepare()这个方法来造一个Looper对象。这样才能顺利使用实例化Handler,并重写抽象方法handleMessage()。
3,待发送的消息最终要发送到哪里去?由2可以知道使用handler.sendMessage()这个方法把消息顺利的发送出去,那么发送出去的消息最终到哪里去了呢?答案是这一条一条的消息最终发送到了消息队列中,消息队列MessageQueue的实例化是在Looper的构造方法中进行的,在造出Looper对象之后已经实例化了MessageQueue,所以这里才能把消息发送到消息队列中。
4,在哪里取出消息?怎么取出消息?既然消息已经发送到消息队列中了,消息的取出肯定是从消息队列中取出,至于怎么取出,这里边的内容比较复杂,不过看源码的话并不是很难。消息发送到消息队列中,这个消息队列在looper.loop()这个方法的作用下开始进行循环,只要有消息,循环的过程中就会取出消息,并且使用dispatch()这个方法进行消息分发。
5,去除的这条消息怎么进行处理?经过4步骤,消息分发之后,会主动调用handleMessage()方法,在这个方法中进行消息的处理。
这就是Android的消息机制的整个流程和所要解决的问题。
关于Handler造成内存泄露的问题,可以参考下面一位大神的博客:
https://www.jianshu.com/p/6a362ea4dfd8