Android异步消息处理线程

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

1.Android异步线程内部结构

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)