Android 線程 Looper.prepare()、Looper.loop() 使用,androidlooper.loop

來源:互聯網
上載者:User

Android 線程 Looper.prepare()、Looper.loop() 使用,androidlooper.loop
最佳化項目過程中發現了一個很Low的問題,整理一下,備忘:說問題之前先看下HandlerThread的定義一個封裝了looper的線程:  
Looper用於封裝了android線程中的訊息迴圈,預設情況下一個線程是不存在訊息迴圈(message loop)的,需要調用Looper.prepare()來給線程建立一個訊息迴圈,調用Looper.loop()來使訊息迴圈起作用,從訊息佇列裡取訊息,處理訊息。註:寫在Looper.loop()之後的代碼不會被立即執行,當調用後mHandler.getLooper().quit()後,loop才會中止,其後的代碼才能得以運行。Looper對象通過MessageQueue來存放訊息和事件。一個線程只能有一個Looper,對應一個MessageQueue。
以下是Android API中的一個典型的Looper thread實現:
//Handler不帶參數的預設建構函式:new Handler(),實際上是通過Looper.myLooper()來擷取當前線程中的訊息迴圈,
//而預設情況下,線程是沒有訊息迴圈的,所以要調用 Looper.prepare()來給線程建立訊息迴圈,然後再通過,Looper.loop()來使訊息迴圈起作用。
[java] view plaincopy

  1. class LooperThread extends Thread  
  2. {  
  3. public Handler mHandler;  
  4. public void run()   
  5. {  
  6. Looper.prepare();  
  7. mHandler = new Handler()   
  8. {  
  9. public void handleMessage(Message msg)   
  10. {  
  11. // process incoming messages here  
  12. }  
  13. };  
  14. Looper.loop();  
  15. }  

另,Activity的MainUI線程預設是有訊息佇列的。所以在Activity中建立Handler時,不需要先調用Looper.prepare()。


那麼遇到了有多Low的問題呢:

項目中重寫了一個HandlerThread,然後定義了post方法,然後在主線程中如下實現:

        AsyncHandler.post(new Runnable() {
            @Override
            public void run() {
                try {
                    Looper.prepare();

   // 一坨要非同步執行的代碼******

                    Looper.loop();
                } catch (Exception e) {
                    // TODO: handle exception
                e.printStackTrace();
                }

那麼明眼人一看就看出問題來了 ,這代碼一跑非同步代碼肯定執行不到啊,為啥呢,且看下prepare的實現:



     /** Initialize the current thread as a looper.
      * This gives you a chance to create handlers that then reference
      * this looper, before actually starting the loop. Be sure to call
      * {@link #loop()} after calling this method, and end it by calling
      * {@link #quit()}.
      */
    public static void prepare() {
        prepare(true);
    }


    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));
    }

So,簡單,卻是問題~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.