Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android之Handler源碼深入解析

Android之Handler源碼深入解析

編輯:關於Android編程

閒著沒事,就來看看源碼,看看源碼的各種原理,會用只是簡單的,知道為什麼才是最牛逼的。

Handler源碼分析那,從使用的步驟來邊用邊分析:

1.創建一個Handler對象:new Handler(getMainLooper(),this);

這是我常用的一個方式,getMainLooper是獲取主線程的Looper,this則是實現CallBack的接口

看一下Handler的構造函數

public Handler() {

this(null, false);

}

public Handler(Callback callback) {

this(callback, false);

}

public Handler(Looper looper) {

this(looper, null, false);

}

public Handler(Looper looper, Callback callback) {

this(looper, callback, false);

}

 

@hide

public Handler(boolean async) {

this(null, async);

}

 

@hide

public Handler(Callback callback, boolean async) {

if (FIND_POTENTIAL_LEAKS) {

final Classklass = 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;

}

 

 

@hide

public Handler(Looper looper, Callback callback, boolean async) {

mLooper = looper;

mQueue = looper.mQueue;

mCallback = callback;

mAsynchronous = async;

}

 

構造函數的最主要代碼作用是參數的初始化賦值:

 

mLooper = looper;mQueue = looper.mQueue;mCallback = callback; mAsynchronous = async;

 

這四個參數是主要的參數了。

 

2.創建一個Message。 Message msg = handler.obtainMessage();

直接調用Handler的源碼:

public final Message obtainMessage()

{

return Message.obtain(this);

}

 

Message中得源碼:

 

public static Message obtain(Handler h) {

Message m = obtain();

m.target = h;

return m;

}

 

 

public static Message obtain() {

synchronized (sPoolSync) {

if (sPool != null) {

Message m = sPool;

sPool = m.next;

m.next = null;

m.flags = 0; // clear in-use flag

sPoolSize--;

return m;

}

}

return new Message();

}

這裡Message是復用的概念,最大能夠保持

private static final int MAX_POOL_SIZE = 50;

50個Message的對象。

sPool變量相當於當前的空的沒有被使用的Message,通過轉換,將當前這個空Message給返回出去。

Message在使用完之後會被回收的,在下面會有提到。

 

3.給Message賦值,並發送Message : msg.what = 100 ; handler.sendMessage(msg);

 

what是Message中得一個儲值變量。

發送Message則在Handler中得最終指向是以下源碼:

 

private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {

msg.target = this;

if (mAsynchronous) {

msg.setAsynchronous(true);

}

return queue.enqueueMessage(msg, uptimeMillis);

}

oK,sendMessage給發送給了MessageQueue類,看MessageQueue怎麼處理的。

boolean enqueueMessage(Message msg, long when) {

 

?...........

 

if (p == null || when == 0 || when < p.when) {

// New head, wake up the event queue if blocked.

msg.next = p;

mMessages = msg;

needWake = mBlocked;

} else {

// Inserted within the middle of the queue. Usually we don't have to wake

// up the event queue unless there is a barrier at the head of the queue

// and the message is the earliest asynchronous message in the queue.

needWake = mBlocked && p.target == null && msg.isAsynchronous();

Message prev;

for (;;) {

prev = p;

p = p.next;

if (p == null || when < p.when) {

break;

}

if (needWake && p.isAsynchronous()) {

needWake = false;

}

}

msg.next = p; // invariant: p == prev.next

prev.next = msg;

}

 

if (needWake) {

nativeWake(mPtr);

}

}

.......

}

 

 

截取了中間重要的代碼說一下。這個是用來干嘛的??

其實就是用來排序的,我們知道的是Message有延遲的消息,延遲消息的時間都是不一樣的,when是有大小的,將後執行的Message放到後面。

MessageQueue不是使用一個集合啊或者使用數組去存放的Message,真正排序的是Message的next變量,next變量存放的是當前Message的下一個Message。

發送之後就執行了一個原生的方法nativeWake,這個在這兒就不去探究了。

 

 

4.handler消息的處理回調Callback.

 

public static void loop() {

 

 

........

 

for (;;) {

Message msg = queue.next(); // might block

 

? ? ?.....

msg.target.dispatchMessage(msg);

 

? ? ? ? ??.......

 

msg.recycleUnchecked();

}

?

? ?......

}

這個那是Looper種的源碼,loop就是循環取MessageQueue中得Message的方法。我去掉了代碼,我們可以看到調用了Messa得target變量,這個變量存放的就是Handler,dispatchMessage就是用來分發Message的方法了。看DispatchMessage的源碼:

 

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

 

這個就少了很多了啊!

看到了把,回調了callback。這樣就完成了整個循環流程。

 

 

說一下上面的
msg.recycleUnchecked()方法。同樣,看源碼:

 

void recycleUnchecked() {

// Mark the message as in use while it remains in the recycled object pool.

// Clear out all other details.

flags = FLAG_IN_USE;

what = 0;

arg1 = 0;

arg2 = 0;

obj = null;

replyTo = null;

sendingUid = -1;

when = 0;

target = null;

callback = null;

data = null;

 

synchronized (sPoolSync) {

if (sPoolSize < MAX_POOL_SIZE) {

next = sPool;

sPool = this;

sPoolSize++;

}

}

}


從方法名上可以知道這個是用來回收Message的。

在Message使用完畢之後,不是將MEssage對象銷毀,而是存放起來,將其下次重復使用。

 

 

Handler運行大概流程就是這樣的了。

Looper的類的源碼分析,回頭再解析。

 

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