Android技术21:Android异步消息处理线程

Android异步消息处理线程,该线程一直处于无限循环之中,每次从Message Queue中读取消息,然后回调消息处理的方法,Handler的HandlerMessage中处理消息。如果消息队列为空,该线程就挂,等待消息队列中有消息进来,就唤醒线程。

1.Android异步线程内部结构

在线程内部有一个或者多个Handler对象,外部程序通过Handler对象向线程发送异步消息,消息经过Handler传递到Message Queue对象中,每个线程内部只包含一个一个消息队列对象,线程主执行函数从消息队列中读取消息,并回调Handler对象方法handlerMessage()。

2.Thread Local Storage

程序员通过Looper类的静态方法prepare()为线程创建消息队列对象。

static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();

1   private static void prepare(boolean quitAllowed) {
2         if (sThreadLocal.get() != null) {
3             throw new RuntimeException("Only one Looper may be created per thread");
4         }
5         sThreadLocal.set(new Looper(quitAllowed));
6     }

线程局部对象TLS,该对象是通过sThreadLocal的set方法设置进去。

3.Looper

Looper对象作用:一是创建消息队列,二是让当前线程提供静态方法loop()进入循环,并从消息队列中读取消息。

1     private Looper(boolean quitAllowed) {
2         mQueue = new MessageQueue(quitAllowed);
3         mRun = true;
4         mThread = Thread.currentThread();
5     }

当需要把一个线程变为异步消息处理线程时,应该在Thread类的run()函数中先调用Looper.prepare()为线程创建一个消息队列对象Message Queue.然后调用Looper.loop()使当前线程进入消息处理循环。

 1   public static void loop() {
 2         final Looper me = myLooper();
 3         if (me == null) {
 4             throw new RuntimeException("No Looper; Looper.prepare() wasn‘t called on this thread.");
 5         }
 6         final MessageQueue queue = me.mQueue;
 7
 8         // Make sure the identity of this thread is that of the local process,
 9         // and keep track of what that identity token actually is.
10         Binder.clearCallingIdentity();
11         final long ident = Binder.clearCallingIdentity();
12
13         for (;;) {
14             Message msg = queue.next(); // might block
15             if (msg == null) {
16                 // No message indicates that the message queue is quitting.
17                 return;
18             }
19
20             // This must be in a local variable, in case a UI event sets the logger
21             Printer logging = me.mLogging;
22             if (logging != null) {
23                 logging.println(">>>>> Dispatching to " + msg.target + " " +
24                         msg.callback + ": " + msg.what);
25             }
26
27             msg.target.dispatchMessage(msg);
28
29             if (logging != null) {
30                 logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
31             }
32
33             // Make sure that during the course of dispatching the
34             // identity of the thread wasn‘t corrupted.
35             final long newIdent = Binder.clearCallingIdentity();
36             if (ident != newIdent) {
37                 Log.wtf(TAG, "Thread identity changed from 0x"
38                         + Long.toHexString(ident) + " to 0x"
39                         + Long.toHexString(newIdent) + " while dispatching to "
40                         + msg.target.getClass().getName() + " "
41                         + msg.callback + " what=" + msg.what);
42             }
43
44             msg.recycle();
45         }

4.Message Queue

从上面看出通过queue.next(),读取一条消息,但是在Framework中并没有消息队列对象,Message Queue两个主要函数读取消息和添加消息,分别为next(),enquenceMessage().但是真正实现并不是在Framework层而是通过JNI在C代码中实现。

1     private native static int nativeInit();
2     private native static void nativeDestroy(int ptr);
3     private native static void nativePollOnce(int ptr, int timeoutMillis);
4     private native static void nativeWake(int ptr);

5.Handler

在构造Handler对象前,必须经过执行过Looper.prepare(),在Looper.loop()函数中,不同的Message对应不同的Handler对象,从而回调不同的handlerMessage()函数。

Android技术21:Android异步消息处理线程,布布扣,bubuko.com

时间: 2024-10-22 11:57:44

Android技术21:Android异步消息处理线程的相关文章

Handler 、 Looper 、Message异步消息处理线程机制( hander消息机制原理)

Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念. 那么什么叫异步消息处理线程呢? 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环.若消息队列为空,线程则会阻塞等待. 详细总结::: 前提,主线程ui,只能刷新页面和处理事件:耗时的数据处理都在子线程中... 那么子线程的数据如何同步到主线程? 那就需要异步消息处理机制Handler .

(转)Android技术积累:图片异步加载

当在ListView或GridView中要加载很多图片时,很容易出现滑动时的卡顿现象,以及出现OOM导致FC(Force Close). 会出现卡顿现象主要是因为加载数据慢,要等数据加载完才能显示出来.可以通过将数据分页显示,以及将耗时的图片加载用异步的方式和图片缓存,这样就可以解决卡顿的问题. 大部分开发者在ListView或GridView加载图片时,都会在getView方法里创建新的线程去异步加载图片.然而,当屏幕快速向下滑动时,每个划过的Item都会调用getView一次,即会创建出很多

Android技术——在Android中的随意视图中找控件

1.在非常多情况下,我们可能不知道控件的id,可是我们却希望在包括这个控件的视图中找到它,能够採用例如以下做法: 例:在Activity的根视图中找出当中全部的Button控件 private void findButton(ViewGroup group, List<Button> result) { if (group != null) { for (int i = 0, j = group.getChildCount(); i < j; i++) { View child = gr

[学习总结]6、Android异步消息处理机制完全解析,带你从源码的角度彻底理解

开始进入正题,我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题,解决的方案应该也是早已烂熟于心,即创建一个Message对象,然后借助Handler发送出去,之后在Handler的handleMessage()方法中获得刚才发送的Message对象,然后在这里进行UI操作就不会再出现崩溃了. 这种处理方式被称为异步消息处理线程,虽然我相信大家都会用,可是你知道它背后的原理是什么样的吗?今天我们就来一起

Android Native层异步消息处理框架

一.前言 在NuPlayer中,可以发现许多类似于下面的代码: 1 //=======================================// 2 NuPlayerDriver::NuPlayerDriver(pid_t pid) 3 : ...... 4 mLooper(new ALooper) 5 ......{ 6 mLooper->setName("NuPlayerDriver Looper"); 7 mLooper->start( 8 false, /

Android异步消息处理机制完全解析,带你从源码的角度彻底理解

转载于:http://blog.csdn.net/guolin_blog/article/details/9991569 之前也是由于周末通宵看TI3比赛,一直没找到时间写博客,导致已经有好久没更新了.惭愧!后面还会恢复进度,尽量保证每周都写吧.这里也是先恭喜一下来自瑞典的Alliance战队夺得了TI3的冠军,希望明年中国战队能够虎起! 开始进入正题,我们都知道,Android UI是线程不安全的,如果在子线程中尝试进行UI操作,程序就有可能会崩溃.相信大家在日常的工作当中都会经常遇到这个问题

Android异步消息处理 Handler Looper Message关系源码分析

# 标签: 读博客 对于Handler Looper Message 之前一直只是知道理论,知其然不知所以然,看了hongyang大神的源码分析,写个总结帖. 一.概念.. Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念. 异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环.若消息队列为空,线程则会阻塞等待. 说了这一堆,那么和Handle

Android 异步消息处理机制 让你深入理解 Looper、Handler、Message三者关系

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38377229 ,本文出自[张鸿洋的博客] 很多人面试肯定都被问到过,请问Android中的Looper , Handler , Message有什么关系?本篇博客目的首先为大家从源码角度介绍3者关系,然后给出一个容易记忆的结论. 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步

Android 异步消息处理机制

转载自博客:http://blog.csdn.net/lmj623565791/article/details/38377229/ 1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步消息处理线程启动后会进入一个无限的循环体之中,每循环一次,从其内部的消息队列中取出一个消息,然后回调相应的消息处理函数,执行完成一个消息后则继续循环.若消息队列为空,线程则会阻塞等待. 说了这一堆,那么和Handler