Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android handler機制源碼解析【異步回調】

android handler機制源碼解析【異步回調】

編輯:關於Android編程

流程總結

Looper.prepare():本線程中保存一個Looper實例,然後該實例中保存一個MessageQueue對象;因為Looper.prepare()在一個線程中只能調用一次,所以MessageQueue在一個線程中只會存在一個。Looper.loop():輪詢MessageQueue,回調msg.target.dispatchMessage(msg)方法。Handler構造方法:得到當前線程中保存的Looper實例,進而與Looper實例中的MessageQueue想關聯。Handler的sendMessage():會給msg的target賦值為handler自身,然後加入MessageQueue中。重寫handleMessage():是msg.target.dispatchMessage(msg)最終調用的方法。

Tip:在Activity的啟動代碼中,已經在當前UI線程調用了Looper.prepare()和Looper.loop()方法。創建handler就不用顯示的調用Looper.prepare()和Looper.loop()

觀察者模式

Looper

創建一個MessageQueue,輪詢MessageQueue

構造方法
private Looper(boolean quitAllowed) {  
        mQueue = new MessageQueue(quitAllowed);  
        mRun = true;  
        mThread = Thread.currentThread();  
}

創建messageQueue
prepare()
public static final void prepare() {  
        if (sThreadLocal.get() != null) {  
            throw new RuntimeException("Only one Looper may be created per thread");  
        }  
        sThreadLocal.set(new Looper(true));  
} 
 

不能被調用2次,有且只有一個
loop() looper方法必須在prepare方法之後運行輪詢,無 -> 阻塞,有 -> msg.target.dispatchMessage(msg);
作用 綁定當前線程,有且只有一個looper實例和MessageQueue,輪詢並通知

handler

消息創建者,異步分發

public Handler() {  
        this(null, false);  
}  
public Handler(Callback callback, boolean async) {  
        if (FIND_POTENTIAL_LEAKS) {  
            final Class klass = getClass();  
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&  
                    (klass.getModifiers() & Modifier.STATIC) == 0) {  
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +  
                    klass.getCanonicalName());  
            }  
        }  
  
        mLooper = Looper.myLooper();  
        if (mLooper == null) {  
            throw new RuntimeException(  
                "Can't create handler inside thread that has not called Looper.prepare()");  
        }  
        mQueue = mLooper.mQueue;  
        mCallback = callback;  
        mAsynchronous = async;  
    }  


mLooper = Looper.myLooper(); 獲取looper
mQueue = mLooper.mQueue;獲取messagequeue

public final boolean sendMessage(Message msg)  
 {  
     return sendMessageDelayed(msg, 0);  
 } 

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {  
       msg.target = this;  
       if (mAsynchronous) {  
           msg.setAsynchronous(true);  
       }  
       return queue.enqueueMessage(msg, uptimeMillis);  
   }  

msg.target = this; => msg.target.dispatchMessage(msg); handler發出的消息,最終會保存到消息隊列中去

Message

dispathMessage

public void dispatchMessage(Message msg) {  
        if (msg.callback != null) {  
            handleCallback(msg);  
        } else {  
            if (mCallback != null) {  
                if (mCallback.handleMessage(msg)) {  
                    return;  
                }  
            }  
            handleMessage(msg);  
        }  
    }  

因為消息的最終回調是由我們控制的,我們在創建handler的時候都是復寫handleMessage方法,然後根據msg.what進行消息處理

private Handler mHandler = new Handler()  
    {  
        public void handleMessage(android.os.Message msg)  
        {  
            switch (msg.what)  
            {  
            case value:  
                  
                break;  
  
            default:  
                break;  
            }  
        };  
    };  


public int what:變量,用於定義此Message屬於何種操作public Object obj:變量,用於定義此Message傳遞的信息數據,通過它傳遞信息public int arg1:變量,傳遞一些整型數據時使用public int arg2:變量,傳遞一些整型數據時使用public Handler getTarget():普通方法,取得操作此消息的Handler對象。

完成調度信息

{@link #post}, {@link #postAtTime(Runnable, long)},{@link #postDelayed}, {@link #sendEmptyMessage},{@link #sendMessage}, {@link #sendMessageAtTime}, and{@link #sendMessageDelayed} methods. The post versions allow

Handler post

mHandler.post(new Runnable()  
        {  
            @Override  
            public void run()  
            {  
                Log.e("TAG", Thread.currentThread().getName());  
                mTxt.setText("yoxi");  
            }  
        });  

Runnable並沒有創建什麼線程,而是發送了一條消息
public final boolean post(Runnable r)  
   {  
      return  sendMessageDelayed(getPostMessage(r), 0);  
   }

private static Message getPostMessage(Runnable r) {  
      Message m = Message.obtain();  
      m.callback = r;  
      return m;  
  }  
在getPostMessage中,得到了一個Message對象,然後將我們創建的Runable對象作為callback屬性,賦值給了此message.

注:

產生一個Message對象,可以new ,也可以使用Message.obtain()Message內部維護了一個Message池用於Message的復用,使用Message.obtain()方法避免使用new 重新分配內存。如果你的message只需要攜帶簡單的int信息,請優先使用Message.arg1和Message.arg2來傳遞信息,這比用Bundle更省內存擅用message.what來標識信息,以便用不同方式處理message

如果不為null,則執行callback回調,也就是我們的Runnable對象。


問題

1,使用Handler 是異步的,它會建立新的線程麼? 不會
2,Handler 是在主線程內麼? 一般都會在主線程內,但也可以在子線程中創建Handler
3,Handler 的 post 和 sendMessage 方法,使用的是一個隊列不安是兩個? 一個
4,子線程中建立一個 handler, 然後sendMessage 會怎麼樣? 會崩潰
5,子線程建立 handler ,構造的時候舒心入主線程的 Looper ? yes




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