Android技術21:Android非同步訊息處理線程,android非同步

來源:互聯網
上載者:User

Android技術21:Android非同步訊息處理線程,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 block15             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 logger21             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 the34             // 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()函數。

 


java或者android實現非同步方式只可以用多線程,有沒有其他的方式

android中有AsyncQueryHandler和AsyncTask都是用來非同步訊息傳遞的,不過本質都是多線程,不過Android幫你封裝好了方便調用而已。希望能夠協助到你!
 
對於Android擷取線程執行完後的結果的問題

其實Google早就意識到這個問題。Message裡有一個send的方法。如下
Message msg = mhandler.obtainMessage(MSG_UPDATE, imgIndex, 0);
mhandler.sendMessage(msg);

然後重寫handler的 handlerMessage方法,如下:
private Handler mhandler = new Handler(){
@Override
public void handleMessage(Message msg){
if(msg.what == MSG_UPDATE){
//你要的操作...

}
}
};

基本上就是這樣啦!
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.