百度为何不收录你的网站产品页,样本之家登录网站,上海外贸学院现在是什么学校,响应式布局如何实现Looper分析
在 Handler 机制中#xff0c;Looper 的作用是提供了一个消息循环 ( message loop ) 的机制#xff0c;用于处理和分发消息。
Looper 是一个线程局部的对象#xff0c;每个线程只能有一个 Looper 对象。它通过一个无限循环来不断地从消息队列中取出消息#x…Looper分析
在 Handler 机制中Looper 的作用是提供了一个消息循环 ( message loop ) 的机制用于处理和分发消息。
Looper 是一个线程局部的对象每个线程只能有一个 Looper 对象。它通过一个无限循环来不断地从消息队列中取出消息并将消息分发给对应的 Handler 进行处理。
在使用 Handler 机制时我们可以通过调用 Looper.prepare() 方法来创建一个Looper对象并通过 Looper.loop() 方法来启动消息循环。在消息循环开始后Looper会不断地从消息队列中取出消息然后将消息分发给对应的 Handler 进行处理。
Handler 可以通过调用 post()、sendMessage() 等方法将消息发送到消息队列中然后由 Looper 负责将这些消息取出并分发给对应的 Handler 进行处理。这样就实现了线程间的消息传递和处理。
Looper还可以通过调用 quit() 方法来终止消息循环停止消息的处理。
下来以主线程内的 Looper 分析下。
Looper 创建/运行
App 运行进程创建后主线程开始运行的入口在 ActivityThread 的 main(String[] args) 方法。
// ActivityThread.java sdk30public static void main(String[] args) {// ...... 一系列的初始化操作。// 创建主线程的 Looper 并设置到 ThreadLocal同时创建了绑定的 MessageQueue。Looper.prepareMainLooper(); // ......ActivityThread thread new ActivityThread(); // 主线程对象创建thread.attach(false, startSeq);if (sMainThreadHandler null) { // 主线程处理各事件的 HandlersMainThreadHandler thread.getHandler();}// ......Looper.loop(); // Looper 开始无限循环从 MessageQueue 中取消息也同时保证了主线程的存活。throw new RuntimeException(Main thread loop unexpectedly exited);
}上面代码中 Looper 的创建与运行就两行。 Looper.prepareMainLooper(); 方法的调用创建了 **主线程 ** 的 Looper 对象并将它设置到了 sThreadLocal 中。 // Looper.java sdk30private 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));
}Deprecated
public static void prepareMainLooper() {prepare(false);synchronized (Looper.class) {if (sMainLooper ! null) {throw new IllegalStateException(The main Looper has already been prepared.);}sMainLooper myLooper();}
}上面代码保证了一个线程只能有一个 Looper 对象 if (sThreadLocal.get() ! null) 判断表明 sThreadLocal 内对应于主线程的 Looper 对象只能存在一个。若主线程运行起来时发现已经有存在的 Looper 对象将抛出异常也就表明 app 进程直接crash。prepareMainLooper() 被标注了 Deprecated Looper 是 public 类在 app 程序中是可以调用 Looper.prepareMainLooper() 方法的。换言之在 sThreadLocal 中已经存在 Looper 对象的情况下可以再次调用方法 Looper.prepareMainLooper()因此在 prepare(boolean quitAllowed) 一开始就先判断是否存在了 Looper 对象。进一步表明一个线程中只能有一个 Looper。赋值 sMainLooper。 这样主线程的 Looper 就创建完成了。 Looper.loop(); 开启了 Looper 的无限循环从 MessageQueue 中取消息附带同时保证了主线程的存活。还负责将 msg 分发给对应的 Handler 执行。 Looper 运行图