Android原始碼分析——Looper,Messagequeue,Message,handler初始化及handler機制簡介
private Looper(boolean quitAllowed) {
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
直接上原始碼可見是個private的構造方法。可見單例模式痕跡明顯。肯定有對外的例項方法。接著看:private static Looper sMainLooper; // guarded by Looper.class
例項在類初始化的時候初始化了。只需要獲取即可。看看有哪些能獲取例項的方法:
prepareMainLooper很熟悉吧。對,就是它。主方法裡面用的就是它。當然註釋裡面說了,主執行緒用來例項化Looper的,你應該永遠也用不到它。然後提示你看prepare()/** * Initialize the current thread as a looper, marking it as an * application's main looper. The main looper for your application * is created by the Android environment, so you should never need * to call this function yourself. See also: {@link #prepare()} *///主執行緒用來例項化Looper的,你應該永遠也用不到它。 public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
這裡第一句程式碼看看。
prepare(false)
這菊花雖然短,但是千萬不要忽略了。它就是那個萬惡的深藏著的Looper例項所在。
如果ThreadLocal.get()不為空,可能你會有疑問sThreadLocal究竟是什麼。後面我會認真考慮寫關於ThreadLocal的技術部落格的。現在只需要立即為一個儲存資料的物件,對外公開了set,get方法即可。private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
sThreadLocal.set(new Looper(quitAllowed));
這裡的quitallowed引數明顯一直沒變,是false會到最開始的私有的初始化函式private looper(boolean quitallowed)。發現其實到這兒我們的Looper例項化已經完事了。quitallowed是給Messagequeue物件例項化傳遞的一個引數罷了。既然這樣子,那就先放放,交給後面的Messagequeue去講它的例項化方法再提。繞了一圈,再來談談輪詢loop()方法。
looper().loop()輪詢方法
先把loop()原始碼奉上。在哪用到就再提一句吧,每次Looper例項化完,必須緊跟著它。因為首先要有這個輪詢器(例項化),然後再將輪訓器運轉起來loop()。
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static void loop() {
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
final MessageQueue queue = me.mQueue;
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
for (;;) {
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
// This must be in a local variable, in case a UI event sets the logger
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
msg.target.dispatchMessage(msg);
if (logging != null) {
logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
}
// Make sure that during the course of dispatching the
// identity of the thread wasn't corrupted.
final long newIdent = Binder.clearCallingIdentity();
if (ident != newIdent) {
Log.wtf(TAG, "Thread identity changed from 0x"
+ Long.toHexString(ident) + " to 0x"
+ Long.toHexString(newIdent) + " while dispatching to "
+ msg.target.getClass().getName() + " "
+ msg.callback + " what=" + msg.what);
}
msg.recycleUnchecked();
}
}
現在可以一行行看程式碼了,先判斷看看有沒有輪訓器?有則繼續,沒有就拋異常。所以,當你看到下面這個異常的時候,你就知道,你肯定沒寫輪訓器。
final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
不要問我me是什麼,me就是Looper例項。
相關推薦
Android原始碼分析——Looper,Messagequeue,Message,handler初始化及handler機制簡介
private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed); mThread = Thread.currentThread(); }直接上原始碼可見是個private的構造
Netflix Eureka原始碼分析(7)——eureka client啟動環境初始化流程
eureka-examples,有一個類,ExampleEurekaClient,就是一個自帶的例子,如果是一個eureka服務,一定會有一個eureka client,服務例項啟動的時候,一定會啟動eureka client,eureka client去向eureka se
Spring原始碼分析(二)-Spring IoC容器的初始化No.2
Spring原始碼分析(一)-Spring IoC容器的初始化No.1中已經分析了Bean的載入過程,本章將分析Bean的例項化過程 本章圍繞refresh().finishBeanFactoryInitialization(beanFactory)方法,
AFNetworking3.1.0原始碼分析(四)詳解AFHTTPRequestSerializer 之初始化方法
1:類圖介紹 在AFHTTPSessionManager 初始化方法中可以看到 AFNetworking 預設使用的網路請求序列化類是AFHTTPRequestSerializer,一下是關於它的類圖: 2:類功能分析: 一:初始化函式: - (instancetyp
Spring原始碼分析(二)-Spring IoC容器的初始化No.1
Spring IoC容器的初始化 Spring原始碼分析(一)中提到了很多類,比如BeanDefinition、BeanDefinitionReader、BeanDefintionParser、BeanWrapper等都是ApplicationContext中
Netty原始碼分析之ChannelPipeline(一)—ChannelPipeline的構造與初始化
Netty中ChannelPipeline實際上類似與一條資料管道,負責傳遞Channel中讀取的訊息,它本質上是基於責任鏈模式的設計與實現,無論是IO事件的攔截器,還是使用者自定義的ChannelHandler業務邏輯都做為一個個節點被新增到任務鏈上。 一、ChannelPipeline的設計與構成 &
kubeadm原始碼分析(內含kubernetes離線包,三步安裝)_Kubernetes中文社群
k8s離線安裝包 三步安裝,簡單到難以置信 kubeadm原始碼分析 說句實在話,kubeadm的程式碼寫的真心一般,質量不是很高。 幾個關鍵點來先說一下kubeadm乾的幾個核心的事: kubeadm 生成證書在/etc/kubernetes/pki目錄下 kubeadm 生成static
Android訊息處理機制、Hanlder機制(Handler、Looper、MessageQueue和Message)
·前言長久以來,我使用Hanlder僅限於它的基本使用:post 和 sendMessage而對於Hanlder的原理和訊息處理機制並不清楚。找了兩篇比較深入的部落格:學習了一下,又對照了原始碼,小有收穫,俗話說“好記性不如爛筆頭”,所以做一下筆記,總結一下,方便以後回顧。·
Android原始碼分析-訊息佇列和Looper
轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/17361775 前言 上週對Android中的事件派發機制進行了分析,這次博主要對訊息佇列和Looper的原始碼進行簡單的分析。大家耐心看下去,其實訊息
基於android原始碼基礎的API文件製作,CHM格式製作
步驟一:生成doc的index.html檔案 1.device\mstar\common\libraries\tvapi\java下新建package.txt,,將此目錄下的子包,全部列出來,放入package.txt,中 如: com.mstar.android.tvap
Android原始碼分析之為什麼在onCreate() 和 onResume() 獲取不到 View 的寬高
轉載自:https://www.jianshu.com/p/d7ab114ac1f7 先來看一段很熟悉的程式碼,可能在最開始接觸安卓的時候,大部分人都寫過的一段程式碼;即嘗試在 onCreate() 和 onResume() 方法中去獲取某個 View 的寬高資訊: 但是列印輸出後,我們會發
Android原始碼分析-Activity的啟動過程
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
Android原始碼分析-全面理解Context
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
從Android原始碼分析Activity載入流程
從Android原始碼分析Activity載入流程 概述:startActivity->startActivityForResult->Instrumentation::execStartActivity->scheduleLaunchActivi
寫一個手機類,屬性:品牌brand,價格price 行為:打電話Call,發簡訊Message,打遊戲Game 要用到this和Private的知識點
初寫手機類 這個程式是初步的程式,還有很多細節沒補上,等到學到後面再逐漸完善了 class Demond_Phone { public static void main(String[] args) { Phone p1 = new Phone();
Android原始碼分析—帶你認識不一樣的AsyncTask(串並行)
前言 什麼是AsyncTask,相信搞過android開發的朋友們都不陌生。AsyncTask內部封裝了Thread和Handler,可以讓我們在後臺進行計算並且把計算的結果及時更新到UI上,而這些正是Thread+Handler所做的事情,沒錯,AsyncTask
Android原始碼分析之簡單工廠模式
模式的定義 簡單工廠模式又稱為靜態方法工廠模式,是由一個工廠物件決定建立哪一個產品類的例項。 使用場景 客戶端需要建立物件、隱藏物件的建立過程,且目標物件型別數量不多的情況下,可以考慮使用簡單工廠模式。 UML類圖 角色介紹 Product 產品的通用介面,定義產
android 原始碼分析開啟mic
1、demo AudioManager audioManager = (AudioManager)getSystemService("audio"); audioManager.setMode(AudioManager.STREAM
React Native 4 for Android原始碼分析 一《JNI智慧指標之介紹篇》
導讀 React Native 釋出以來將近一年多了,也被抄的火爆到不行,包括RN的中文網和各種資料也很多,加之SE5,Se6語法升級,學習成本並不在RN環境搭建和入門,關鍵還是對JS的掌握入門,不管你是用Native開發,h5開發,還是React
中國象棋android原始碼分析
大家好,今天我給大家分享一箇中國象棋的Android遊戲原始碼。先來一張圖片看看效果。 1、原始碼結構 所有類都放置到com.bn.chess包裡. 2、類及類關係介紹 (1)Chess_DJB_Activity->Welcom