说来惭愧,工作三年了,都没了彻底解Android的几个重要的机制,只是会用,最近找工作被问的懵逼,所以我决定彻底了解这些机制,今天说的是Handler机制。
Handler机制每个人都能说出个大概,但是具体怎么实现的,估计很多人都说不出来,看源码又很枯燥,我就对着几个博客,尝试着自己实现自己的Handler机制,而且我成功了,贴出自己的小Demo,希望能帮助到各位同行。
package com.example.handlerdemo;
import android.content.Context;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MyHandlerActivity extends AppCompatActivity {
private static String TAG = "MyHandlerActivity";
public MyHanler mHander;
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_my_handler);
mHander = new MyHanler() {
@Override
public void sendMessage(MyMessage myMessage) {
// 模拟将Msg放人MessageQueue,这里只有一条消息,所以只有简单的赋值操作
Log.e(TAG, "handlerMessage");
this.msg = myMessage;
}
@Override
public void handleMessage(MyMessage myMessage) {
Log.e(TAG, "handleMessage");
Toast.makeText(mContext, "我的自定义Handler", Toast.LENGTH_SHORT).show();
}
};
MyThread childThread = new MyThread();
childThread.start();
}
@Override
protected void onResume() {
super.onResume();
// 在主线程中启动消息循环,拿到不为空的消息对象后调用handleMessage,
// 这样就实现了子线程发送的消息,并引发主线程中的方法调用
mHander.loop();
}
/*
模拟Handler,简化没有Loop和MQ
只能接受一条消息
我一开始尝试直接在MyThread中调用MyHanler的handleMessage方法,但这样会报错
因为直接调用MyHanler的方法,这个方法其实还是在子线程中运行,所以弹Toast的时候会报异常
而MyHanler发送一个消息对象,在MyHanler中启动一个死循环拿消息再调用handleMessage就是在自己的线程中执行
这就是为什么Android要用一个复杂的Handler机制来实现线程间通信
*/
abstract class MyHanler {
MyMessage msg;
public MyHanler() {
}
public void loop() {
// 模拟Loop的消息循环
for (; ; ) {
Log.w(TAG, "looping");
if (null != msg) {
Log.e(TAG, "getMessage");
handleMessage(msg);
return;
}
}
}
abstract void sendMessage(MyMessage myMessage);
abstract void handleMessage(MyMessage myMessage);
}
class MyThread extends Thread {
@Override
public void run() {
// mHander.handlerMessage(0);
MyMessage msg = new MyMessage(0); // 实例化消息对象
mHander.sendMessage(msg);
}
}
}
相信Android的Handler机制是在这个原理上完善的。如有不对,请指正