資源描述:
《android消息處理機制》由會員上傳分享,免費在線閱讀,更多相關(guān)內(nèi)容在應(yīng)用文檔-天天文庫。
1、Android消息處理機制(Handler、Looper、MessageQueue與Message)Android是消息驅(qū)動的,實現(xiàn)消息驅(qū)動有幾個要素:1.消息的表示:Message2.消息隊列:MessageQueue3.消息循環(huán),用于循環(huán)取出消息進行處理:Looper4.消息處理,消息循環(huán)從消息隊列中取出消息后要對消息進行處理:Handler平時我們最常使用的就是Message與Handler了,如果使用過HandlerThread或者自己實現(xiàn)類似HandlerThread的東西可能還會接觸到Looper,而MessageQueue是Looper內(nèi)部使用的,對于
2、標準的SDK,我們是無法實例化并使用的(構(gòu)造函數(shù)是包可見性)。我們平時接觸到的Looper、Message、Handler都是用JAVA實現(xiàn)的,Android做為基于Linux的系統(tǒng),底層用C、C++實現(xiàn)的,而且還有NDK的存在,消息驅(qū)動的模型怎么可能只存在于JAVA層,實際上,在Native層存在與Java層對應(yīng)的類如Looper、MessageQueue等。?初始化消息隊列首先來看一下如果一個線程想實現(xiàn)消息循環(huán)應(yīng)該怎么做,以HandlerThread為例:publicvoidrun(){mTid=Process.myTid();Looper.prepare();
3、synchronized(this){mLooper=Looper.myLooper();notifyAll();}Process.setThreadPriority(mPriority);onLooperPrepared();Looper.loop();mTid=-1;}?主要是紅色標明的兩句,首先調(diào)用prepare初始化MessageQueue與Looper,然后調(diào)用loop進入消息循環(huán)。先看一下Looper.prepare。publicstaticvoidprepare(){prepare(true);}privatestaticvoidprepare(boo
4、leanquitAllowed){if(sThreadLocal.get()!=null){thrownewRuntimeException("OnlyoneLoopermaybecreatedperthread");}sThreadLocal.set(newLooper(quitAllowed));}重載函數(shù),quitAllowed默認為true,從名字可以看出來就是消息循環(huán)是否可以退出,默認是可退出的,Main線程(UI線程)初始化消息循環(huán)時會調(diào)用prepareMainLooper,傳進去的是false。使用了ThreadLocal,每個線程可以初始化一個Loo
5、per。再來看一下Looper在初始化時都做了什么:privateLooper(booleanquitAllowed){mQueue=newMessageQueue(quitAllowed);mRun=true;mThread=Thread.currentThread();}MessageQueue(booleanquitAllowed){mQuitAllowed=quitAllowed;nativeInit();}?在Looper初始化時,新建了一個MessageQueue的對象保存了在成員mQueue中。MessageQueue的構(gòu)造函數(shù)是包可見性,所以我們是無
6、法直接使用的,在MessageQueue初始化的時候調(diào)用了nativeInit,這是一個Native方法:staticvoidandroid_os_MessageQueue_nativeInit(JNIEnv*env,jobjectobj){NativeMessageQueue*nativeMessageQueue=newNativeMessageQueue();if(!nativeMessageQueue){jniThrowRuntimeException(env,"Unabletoallocatenativequeue");return;}nativeMessa
7、geQueue->incStrong(env);android_os_MessageQueue_setNativeMessageQueue(env,obj,nativeMessageQueue);}staticvoidandroid_os_MessageQueue_setNativeMessageQueue(JNIEnv*env,jobjectmessageQueueObj,NativeMessageQueue*nativeMessageQueue){env->SetIntField(messageQueueObj,gMessageQueueClassInfo.