Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 線程 Looper.prepare()、Looper.loop() 使用

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

編輯:關於Android編程

優化項目過程中發現了一個很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] 
  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,簡單,卻是問題~

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved