背景
有时候需要在子线程中进行耗时的 I/O 操作,读取文件或者访问网络等,当耗时操作完成以后可能需要在 UI 上做一些改变,由于 Android 开发规范的限制,不能在子线程中访问 UI 控件,否则就会触发程序异常,这个时候通过 Handler 就可以将更新 UI 的操作切换到主线程中执行。
相关类
- Handler
- Looper(消息循环)
- Message(消息)
- MessageQueue(存储消息)
Handler
package android.os;
public class Handler
public Handler(Callback callback, boolean async) {
...// 省略其他代码
// 获取当前线程的 Looper 对象,如果没有则抛出异常
mLooper = Looper.myLooper();
if (mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread " + Thread.currentThread()
+ " that has not called Looper.prepare()");
}
// 绑定消息队列对象
mQueue = mLooper.mQueue;
mCallback = callback;
mAsynchronous = async;
}
创建 Handler
对象时,自动关联当前线程的 Looper
对象,绑定相应的消息队列对象。
Looper
package android.os;
public final class Looper
// Looper初始化
public static void prepare()
// 消息循环
public static void loop()
// ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {
// 创建消息队列对象,当创建Looper实例时,会自动创建与之关联的消息队列实例
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
FAQ
android 主线程中 Looper.loop() 为什么不会造成程序 ANR?