編輯:關於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的類的源碼分析,回頭再解析。
結構 繼承關系 public abstract class AsyncTask extends Object java.lang.Object andr
1.修改SDK版本: 打開File--Project Structure... Modules--app--Properties
接著AppWidget基礎學習,今天是一個“進階版”的小例子,用來檢驗一下自己的學習效果。於是就做了一個擲骰子的Widget。方便大家觀看,先截圖如下: &nb
一、簡介1.Android ORM介紹?在平時的開發過程中,大家一定會或多或少地接觸到 SQLite。然而在使用它時,我們往往需要做許多額外的工作,像編寫 SQL 語句與