Android訊息機制Message訊息池
這篇文章主要說下Android在實現Message類的時候使用的一個所謂的訊息池的問題。
我們在使用Android的訊息迴圈時,一般按照下面的方式使用,為了使執行緒具有訊息迴圈如下:
//實現自己的Handler類,重寫handlerMessage()方法
- private class MyHandler extends Handler{
- @Override
- public void handleMessage(Message msg) {
- if(msg.what==1){
- textView.setText(""+msg.arg1);//獲得傳遞過來的資料
- }
- super.handleMessage(msg);
- }
- }
線上程的run()方法裡呼叫Looper.prepare(),例項化一個Handler物件,呼叫Looper.loop()使執行緒進入訊息迴圈
- public void run(){
- Looper.prepare();
- //dosomething else
- handler=new MyHandler();
- Looper.loop();
- }
Handler物件的例項話必須在Looper.prepare()之後。
當我們要給具有訊息迴圈的執行緒傳送訊息時,我們先要獲得具有訊息迴圈的執行緒的 Handler 物件(或者先獲取具有訊息迴圈的執行緒的Looper物件,再使用這個Looper物件構造Handler物件),構造一個Message物件,然後呼叫Handler物件的sendMessage方法
- Message message=Message.obtain();
- message.what=1;
- message.arg1=count;
- handler.sendMessage(message);
說了這麼多,現在就來說下Message裡的訊息池問題,我們先看Message的靜態成員方法 Message.obtain();
- // sometimes we store linked lists of these things
- /*package*/ Message next;
- private static final Object sPoolSync = new Object();
- private static Message sPool;
- private static int sPoolSize = 0;
- private static final int MAX_POOL_SIZE = 50;
- /**
- * Return a new Message instance from the global pool. Allows us to
- * avoid allocating new objects in many cases.
- */
- public static Message obtain() {
- synchronized (sPoolSync) {
- if (sPool != null) {
- Message m = sPool;
- sPool = m.next;
- m.next = null;
- sPoolSize--;
- return m;
- }
- }
- return new Message();
- }
在這個類中sPool代表這個訊息池的頭訊息,sPoolSize表示訊息池中可用的訊息的個數即沒有被使用的Message物件的個數,next表示下一個可用的訊息Message物件。
可以看到obtain()方法說會從全域性訊息池中取訊息,假設是第一次獲得一個Message物件,那麼sPool肯定為null,也就說第一次獲取訊息Message物件時是還沒有訊息池的,必須通過Message的構造方法獲取一個Message物件的,Message的構造方法什麼也沒幹
- /** Constructor (but the preferred way to get a Message is to call {@link #obtain() Message.obtain()}).
- */
- public Message() {
- }
那這就有點奇怪了,它的訊息池是什麼時候初始化呢?難道不是先new幾個Message物件然後存著?這是我們注意到Message類的另一個成員方法recycle(),注意這個方法不是靜態的.
- /**
- * Return a Message instance to the global pool. You MUST NOT touch
- * the Message after calling this function -- it has effectively been
- * freed.
- */
- public void recycle() {
- clearForRecycle();
- synchronized (sPoolSync) {
- if (sPoolSize < MAX_POOL_SIZE) {
- next = sPool;
- sPool = this;
- sPoolSize++;
- }
- }
- }
裡面的clearForRecycle()方法只是把一些成員變數置為null,以便垃圾回收
- /*package*/ void clearForRecycle() {
- flags = 0;
- what = 0;
- arg1 = 0;
- arg2 = 0;
- obj = null;
- replyTo = null;
- when = 0;
- target = null;
- callback = null;
- data = null;
- }
從這裡我們就可以發現,訊息池中Message的物件是通過recycle()放進去的. 但是我們自己並沒有呼叫recycle()方法,那這個方法是在哪裡呼叫的?看下Looper的原始碼就知道,在Looper的loop()方法的最後呼叫了Message物件msg的recycle()方法來回收這個Message物件,通過recycle()將這個Message物件的資料清空然後連結到訊息池中(採用的頭插法)。
相關文章
- Android 訊息處理機制:Handler|MessageAndroid
- Android訊息傳遞之Handler訊息機制Android
- OC訊息機制,訊息轉發機制
- android訊息機制—HandlerAndroid
- 理解 Android 訊息機制Android
- Android訊息機制HandlerAndroid
- Android 之訊息機制Android
- Android的訊息機制Android
- 訊息機制
- 訊息機制篇——初識訊息與訊息佇列佇列
- android之 Android訊息機制Android
- Android訊息處理機制(Handler、Looper、MessageQueue與Message)AndroidOOP
- Android非同步訊息機制Android非同步
- Android訊息機制Handler用法Android
- Android 訊息機制詳解Android
- Android訊息機制(七) RxjavaAndroidRxJava
- iOS訊息機制iOS
- SAP訊息機制
- [Android進階]Android訊息機制Android
- Android Handler 訊息機制詳述Android
- Android的Handler訊息機制 解析Android
- 深入理解Android訊息機制Android
- Android訊息機制原始碼分析Android原始碼
- Rabbitmq可靠訊息投遞,訊息確認機制MQ
- JMS java 訊息機制Java
- Windows訊息機制概述Windows
- Android 訊息機制詳解(Android P)Android
- 全面剖析Android訊息機制原始碼Android原始碼
- 深入理解 Android 訊息機制原理Android
- 深入探索Android訊息機制之HandlerAndroid
- 淺析Android中的訊息機制Android
- Android Handler機制之訊息池的擴充套件 SimplePool與SynchronizedPoolAndroid套件synchronized
- Android程式間通訊–訊息機制及IPC機制實現薦Android
- RabbitMQ訊息佇列(九):Publisher的訊息確認機制MQ佇列
- flutter 訊息傳遞機制Flutter
- RabbitMQ 訊息確認機制MQ
- 重拾 ObjC 訊息機制OBJ
- 簡析Windows訊息機制Windows