日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

详细讲解Android中的Message的源码

發布時間:2025/5/22 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 详细讲解Android中的Message的源码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

相信大家對于Android中的Handler是在為熟悉不過了,但是要知道,Handler就其本身而言只是一個殼子,真正在內部起到作用的是Message這個類,對于Message這個類,相信大家也不會陌生,正如大家經常用到的Message.obtain()的方法一樣。但是大家又是否知道obtain()方法里面為我們做了哪些操作了,下面我就帶領大家進行Message的王國,去一探究竟吧。

首先映入眼簾的是這樣的一行代碼:

?

?
1 public final class Message implements Parcelable


不用多說,Message實現了Parcelable的接口,也就是說經過Message封裝的數據,可以通過Intent與IPC進行傳輸。既然實現了Parcelable接口,那么在Message方法中必不可少這三個方法:1)writeToParcel 2)describeContents 3)createFromParcel。

?

下面我們需要關注的四個成員變量分別是:

1)public int what

2)public int arg1

3)public int arg2

4)public Object obj


我們經常是用到這樣的幾個參數,但是其真實的含義是否真正的理解呢?只要google的內部的注釋才是真正的可靠的。

1)用戶定義消息的識別碼,以便于系統識別出當前的消息是關于什么的。由于每一個Handle對于自己的消息的識別碼都有自己的命名空間。所以我們也就不用擔心各個不同的Handler之間會存在沖突的情況。

2)其中第二個參數與第三個參數的意義是一樣的,注釋上是這樣說明的,這兩個參數,如果用戶只是需要傳輸簡單的int類型的數據,相比較于setData(Bundle bundle),代價更低。

3)第四個參數,按照注釋上的說明,是這樣理解的:這是一個發送給接受者的一個隨意的數據,如果使用Messager來進行發送數據進行跨進程的通信,那么當前的obj如果實現了Parcelable就一定不能夠為空指針,對于其他的數據的傳輸,我們一般使用setData方法就可以了。但是需要注意的是,對于高于android.os.Build.VERSION_CODES#FROYO的版本,這里的Parcelable對象是不支持的。


上面的變量講完了以后,接下來,我們還需要講解另外的一組常量的定義:

?

?
1 2 3 4 5 private static final Object sPoolSync = new Object(); private static Message sPool; private static int sPoolSize = 0; //池塘里最大的尺寸 private static final int MAX_POOL_SIZE = 50;


乍一看,大家可能不理解上面四個變量的定義,如果我提醒一下大家,Android中的Message是可以重用的,那么相信大家就能夠大致猜測到這四個變量的含義了。

?

1、第一個變量其實就是充當鎖的作用,避免多線程爭搶資源,導致臟數據

2、sPool這個變量可以理解為消息隊列的頭部的指針

3、sPoolSize是當前的消息隊列的長度

4、定義消息隊列緩存消息的最大的長度。

?

Ok,到這里,Message的成員變量已經講解完畢,接下來主要是講解其中的Api方法。

第一個方法就是大家經常用到的obtain方法,而且不帶任何的參數:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 public static Message obtain() { ????????synchronized (sPoolSync) { ????????????if (sPool != null) { ????????????????Message m = sPool; ????????????????sPool = m.next; ????????????????m.next = null; ????????????????sPoolSize--; ????????????????return m; ????????????} ????????} ????????return new CustomMessage(); ????}www.2cto.com

首先為了避免多線程進行爭搶資源,給sPoolSync進行加鎖。首先判斷當前的隊列的指針是否為空,如果當前的指針已經不為空,當前的隊列的頭部的消息就是可以重用并且被取出,那么當前的隊列的頭指針指向當前的消息的下一個消息,也就是m.next,同時把取出的消息的尾部指針置為null,隊列的長度減1.

?

第二個方法:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public static Message obtain(Message orig) { ????????Message m = obtain(); ????????m.what = orig.what; ????????m.arg1 = orig.arg1; ????????m.arg2 = orig.arg2; ????????m.obj = orig.obj; ????????m.replyTo = orig.replyTo; ????????if (orig.data != null) { ????????????m.data = new Bundle(orig.data); ????????} ????????m.target = orig.target; ????????m.callback = orig.callback; ????????return m; ????}

我們可以看到,這個方法相對于上面的方法多了一個orig的參數,從上面的代碼我們可以看到,首先從隊列中取出Message的對象,然后對其中的參數的對象的各個數據進行逐一的拷貝,并最終返回對象。

?

第三個方法如下:

?

?
1 2 3 4 5 public static Message obtain(Handler h) { ????????Message m = obtain(); ????????m.target = h; ????????return m; ????}

不用多說,這個函數中為當前創建的消息指定了一個Handler對象,因為我們知道Handler是Message的最終的目的地。

?

?

?
1 2 3 4 5 6 public static Message obtain(Handler h, Runnable callback) { ????????Message m = obtain(); ????????m.target = h; ????????m.callback = callback; ????????return m; ????}

相對于上面的方法,這里面多了一行m.callback = callback,按照注釋上面的說明,當一些消息真正的被執行的時候,callback這個Runnbale方法將會被觸發執行的。

?

接下來有一系列的方法的邏輯是差不多的,我們取其中的一個進行講解:

?

?
1 2 3 4 5 6 7 8 public static Message obtain(Handler h, int what, int arg1, int arg2) { ????????Message m = obtain(); ????????m.target = h; ????????m.what = what; ????????m.arg1 = arg1; ????????m.arg2 = arg2; ????????return m; ????}

也就是說創建一個Message的時候,順便可以為這個Message提供一些邏輯上需要的參數。

?

消息有創建,那么就必然存在回收的概念,下面我們一起來看一下:

?

?
1 2 3 4 5 6 7 8 9 10 public void recycle() { ????????clearForRecycle(); ????????synchronized (sPoolSync) { ????????????if (sPoolSize < MAX_POOL_SIZE) { ????????????????next = sPool; ????????????????sPool = this; ????????????????sPoolSize++; ????????????} ????????} ????}
void clearForRecycle() { flags = 0; what = 0; arg1 = 0; arg2 = 0; obj = null; replyTo = null; when = 0; target = null; callback = null; data = null; }



?

?
1

在clearForRecycle這個函數中,是做一些回收的預處理的操作,該置為0的參數置為0,該置為null的參數置為null。在recycle的函數中,只要當前的緩存的隊列的長度沒有超過上限,將當前的消息添加到隊列的尾部。

?

下面的方法是關于實現Parcelable所需要的方法:

?

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 public static final Parcelable.Creator<custommessage> CREATOR ????????????= new Parcelable.Creator<custommessage>() { ????????public Message createFromParcel(Parcel source) { ????????????Message msg = Message.obtain(); ????????????msg.readFromParcel(source); ????????????return msg; ????????} ????????? ????????public Message[] newArray(int size) { ????????????return new Message[size]; ????????} ????}; ????????? ????public int describeContents() { ????????return 0; ????} ????public void writeToParcel(Parcel dest, int flags) { ????????if (callback != null) { ????????????throw new RuntimeException( ????????????????"Can't marshal callbacks across processes."); ????????} ????????dest.writeInt(what); ????????dest.writeInt(arg1); ????????dest.writeInt(arg2); ????????if (obj != null) { ????????????try { ????????????????Parcelable p = (Parcelable)obj; ????????????????dest.writeInt(1); ????????????????dest.writeParcelable(p, flags); ????????????} catch (ClassCastException e) { ????????????????throw new RuntimeException( ????????????????????"Can't marshal non-Parcelable objects across processes."); ????????????} ????????} else { ????????????dest.writeInt(0); ????????} ????????dest.writeLong(when); ????????dest.writeBundle(data); ????????Messenger.writeMessengerOrNullToParcel(replyTo, dest); ????} ????private void readFromParcel(Parcel source) { ????????what = source.readInt(); ????????arg1 = source.readInt(); ????????arg2 = source.readInt(); ????????if (source.readInt() != 0) { ????????????obj = source.readParcelable(getClass().getClassLoader()); ????????} ????????when = source.readLong(); ????????data = source.readBundle(); ????????replyTo = Messenger.readMessengerOrNullFromParcel(source); ????}</custommessage></custommessage>

?

Ok,Message的內核源碼的剖析就講解到這里,相信大家以后再用到這個類的時候會有更深的理解啦。

?

結伴旅游,一個免費的交友網站:www.jieberu.com

推推族,免費得門票,游景區:www.tuituizu.com

轉載于:https://www.cnblogs.com/rabbit-bunny/p/4200381.html

總結

以上是生活随笔為你收集整理的详细讲解Android中的Message的源码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。