Android 消息机制深入源码分析 [ 一 ]
Android 消息机制之 ThreadLocal 深入源码分析 [ 二 ]
Android 消息机制之 Looper 深入源码分析 [ 三 ]
Android 消息机制之 Message 与消息对象池的深入源码分析 [ 四 ]
Android 消息机制之 MessageQueue 深入源码分析 [ 五 ]
Android 消息机制之初识Handler [ 六 ]
Android 消息机制之 Handler 发送消息的深入源码分析 [ 七 ]
Android 消息机制之 MessageQueue.next() 消息取出的深入源码分析 [ 八 ]
Android 消息机制之消息的其他处理深入源码分析 [ 九 ]
Android 消息机制总结 [ 十 ]
前几章分解学习了 ThreadLocal
, Looper
, Message
, MessageQueue
等相关的知识, 本章节开始正式学习 Android 中消息机制的重中之重 Handler
. 那么让我们正式开始学习吧.
1. 什么是 Handler
- Handler 是一个可以通过关联一个消息队列来发送和处理消息, 发送或处理 Runnable 对象的一个处理程序.
- 每个 Handler 都关联一个单个的线程和消息队列. 当我们创建一个新的 Handler 的时候, 它就绑定到一个线程上或者线程上的消息队列, 从那个时候起, 这个 Handler 就将为这个消息队列提供消息或者 Runnable 对象处理消息队列释放出来的消息或者 Runnable 对象.
2. Handler 有什么用
- 安排消息和 Runnable 对象在未来执行.
- 将用户的一个动作放在不同的线程上执行.
3. 构造函数
Handler 的构造函数一共有七个, 六个是有参, 一个无参的, 所有的构造函数都为 public
- 1.public Handler()
- 2.public Handler(Callback callback)
- 3.public Handler(Looper looper)
- 4.public Handler(Looper looper, Callback callback)
- 5.public Handler(boolean async)
- 6.public Handler(Callback callback, boolean async)
- 7.public Handler(Looper looper, Callback callback, boolean async)
这七个构造函数, 又将分为两类. 分别为两个参数的 1. 2. 5. 6 和 三个参数的 3. 4. 7. 接下来将对这个构造函数逐个分析学习.
1. public Handler()
public Handler() {
this(null, false);
}
- 解析:
2. public Handler(Callback callback)
public Handler(Callback callback) {
this(callback, false);
}
- 解析:
5. public Handler(boolean async)
public Handler(boolean async) {
this(null, async);
}
- 解析:
以上是一个无参和两个有参的, 1. 2. 5. 但是他们归根结底调用的都是构造函数 6. 所以现在一起看下构造函数 6.
6. public Handler(Callback callback, boolean async)
public Handler(Callback callback, boolean async) {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> klass = getClass();
//如果是匿名类, 内部类, 局部类,且没有声明 static,则存在内存泄露风险,所以打印日志进行提醒
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
//获得当前线程的 Looper
mLooper = Looper.myLooper();
//如果当前线程没有 Looper,则说明没有还没有调用 Looper.loop,抛异常
if (mLooper == null) {
throw new RuntimeException("Can't create handler inside thread " + Thread.currentThread() + " that has not called Looper.prepare()");
}
//把 Looper 的 Queue 赋值给 Handler 的 mQueue
mQueue = mLooper.mQueue;
//赋值给 callback
mCallback = callback;
//赋值 mAsynchronous
mAsynchronous = async;
}
- 解析:
下面是三个参数的构造函数.
3. public Handler(Looper looper)
public Handler(Looper looper) {
this(looper, null, false);
}
- 解析
4. public Handler(Looper looper, Callback callback)
public Handler(Looper looper, Callback callback) {
this(looper, callback, false);
}
7. public Handler(Looper looper, Callback callback, boolean async)
public Handler(Looper looper, Callback callback, boolean async) {
mLooper = looper;
mQueue = looper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
- 解析:
综合 7 个构造函数, 可以发现其实构造函数的本质都是给下面四个本地变量赋值
mLooper
mQueue
mCallback
mAsynchronous
构造函数总结
- 如果
Handler
的构造中没有给Looper
, 则使用默认的Looper
, 也就是在当前线程ThreadLocal
中关联的Looper
.
通过ThreadLocal.Looper.mQueue
来给Handler.mQueue
赋值.
实现Handler, Looper, MessageQueue
三者的绑定. - 通过构造函数来设置
Callback
的回调接口, 不设置则为null
. - 通过
mAsynchronous
来控制是同步还是异步, 而mAsynchronous
的默认值为false
.mAsynchronous
可以通过构造函数来设置.
最后来说一下回调接口, 也就是 Handler.Callback 接口
public interface Callback {
public boolean handleMessage(Message msg);
}
- 官方翻译:
- 理解
class myHandler extends Handler{
public myHandler(@Nullable Callback callback) {
super(callback);
}
@Override
public void handleMessage(@NonNull Message msg) {
Log.e("myHandler","___what=" + msg.what);
super.handleMessage(msg);
}
}
public class MainActivity extends AppCompatActivity {
Button button1,button2;
private static myHandler handler = new myHandler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
if(msg.what == 100){
Log.e("myHandler","___Callback=" + msg.what);
return true;
}
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = findViewById(R.id.button1);
button2 = findViewById(R.id.button2);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 100;
handler.sendMessage(message);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Message message = Message.obtain();
message.what = 1000;
handler.sendMessage(message);
}
});
}
}
- 点击
button1
, 打印的是___Callback=100
, 拦截了消息 - 点击
button2
, 打印的是___what=1000
, 接收到了消息.
这是我对 Callback.handleMessage
的简单理解. 平时我们估计都不会经常用到这个 Callback
, 估计一般用到的都是无参的 Handler
.
本章对 Handler
的初识就到这里就结束了, 下一章会开始 Handler
对消息的发送进行分析和学习.