一個(gè)線程創(chuàng)建消息循環(huán)的步驟
Looper.perpareLoop();
Handler mhandler = new Handler();
Looper.loop();
首先prepare是一個(gè)靜態(tài)函數(shù),可以不實(shí)例化對(duì)象進(jìn)行訪問
private static final ThreadLocal sThreadLocal = new ThreadLocal();
public static final void prepare() {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper());
}
final MessageQueue mQueue;
private Looper() {
mQueue = new MessageQueue();
mRun = true;
mThread = Thread.currentThread();
}
final MessageQueue mQueue;
final Looper mLooper;
public Handler() {
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Handler> 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 = null;
}
首先它會(huì)使用ThreadLocal變量,關(guān)于ThreadLocal,它的作用是使每個(gè)線程獲得安全的變量拷貝(里面的具體實(shí)現(xiàn)應(yīng)該會(huì)有加鎖,通過Map實(shí)現(xiàn)一些存儲(chǔ),只是猜測(cè)沒有看具體代碼)
ps:其實(shí)使用ThreadLocal也是為了代碼實(shí)現(xiàn)簡(jiǎn)單,不復(fù)雜,盡量結(jié)構(gòu)化
從代碼中可以看出,在Looper創(chuàng)建的時(shí)候同時(shí)創(chuàng)建的MessageQueue,
在創(chuàng)建Handler的時(shí)候通過Looper.myLooper();獲得了looper的實(shí)例(內(nèi)部實(shí)現(xiàn)應(yīng)該是類似于map的數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)了線程的id,獲得了looper,以及messagequeue)
同時(shí)初始化了mCallback.
剩下的就是handler發(fā)送消息的操作,首先它會(huì)sendmessage(msg),這時(shí)會(huì)調(diào)用到enqueuemessage將消息加入到隊(duì)列,加入完成之后messagequeue的next函數(shù)會(huì)被喚醒,進(jìn)行消息分發(fā),同時(shí)looper的阻塞函數(shù)也會(huì)被喚醒,進(jìn)行消息的處理
msg.target.dispatchMessage(),讓handler對(duì)消息進(jìn)行處理。
注意:關(guān)于messagequeue的實(shí)現(xiàn)其實(shí)并不是我們想象的那樣簡(jiǎn)單,如果深入的jni層的話,最后會(huì)看到它是用linux層去實(shí)現(xiàn)的
http://www.cnblogs.com/angeldevil/p/3340644.html
Native層的Looper使用了epoll。初始化了一個(gè)管道,用mWakeWritePipeFd與mWakeReadPipeFd分別保存了管道的寫端與讀端,并監(jiān)聽了讀端的EPOLLIN事件。注意下初始化列表的值,mAllowNonCallbacks的值為false。
上面這篇博客還是講解的比較清晰,從java層到c++層,讓我們了解到了android系統(tǒng)最本質(zhì)的東西