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

歡迎訪問 生活随笔!

生活随笔

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

Android

Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家

發布時間:2024/9/27 Android 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android? Intent傳遞數據底層分析詳細介紹

我們知道在Activity切換時,如果需要向下一個ActivityB傳遞數據,可以借助Intent對象的putExtra方法。

但是不知各位有沒有想過這樣一個問題:ActivityB中獲取到的對象跟上一個Activity中的那個對象有什么關系?

換句話說就是,我在ActivityB中通過Intent獲取的對象跟ActivityA中的那個對象,有沒有可能是同一個對象?

按照常理來說,博主提出一個設想后續的就是證明過程了,但是我要遺憾的告訴你,這里并非是同一個對象。(PS:廢話,如果是同一個對象,那還有EventBus這些東西什么事兒 T_T)

那么問題又來了,這兩個Activity都在同一個進程里面,甚至都在同一個線程里面,數據本來就是可以共享的,為什么從一個Activity傳到另一個Activity之后,就不是一個對象了呢?它從什么時候變成另外的對象的呢?

不著急,且聽我慢慢道來。

Intent是什么東西?

public class Intent implements Parcelable, Cloneable

上面是Intent類的完整聲明,可以知道它實現了Parcelable接口。Parcelable接口是什么呢?這東西是Android上專門用來對數據進行序列化的,并且在跨進程通訊時Parceable對象是可以直接傳輸的。

接下來我們來看看將數據放入Intent的時,做了哪些處理。

以String為例,先看putExtra方法的代碼

public Intent putExtra(String name, String value) {

if (mExtras == null) {

mExtras = new Bundle();

}

mExtras.putString(name, value);

return this;

}

很簡單,就是將數據放入mExtras這個Bundle對象中,順便說一句Bundle類也實現了Parcelable接口。繼續往下跟代碼

public void putString(@Nullable String key, @Nullable String value) {

unparcel();

mMap.put(key, value);

}

內部就是將數據放入一個Map中保存。到這里數據放入Intent的過程就完成了,實際上就是Intent中有一個Bundle對象,而這個Bundle對象中又有一個Map,然后數據就保存在這里。至于那個unparcel()方法與我們的分析過程無關,有興趣的讀者可以去研究一下。

然后,我們再看取數據的過程。

繼續以String作為例子,看Intent中的代碼

public String getStringExtra(String name) {

return mExtras == null ? null : mExtras.getString(name);

}

mExtras應該很熟悉了,這是個Bundle對象,剛剛保存數據的時候就是把數據保存在它里面的。再看它的getString方法

public String getString(@Nullable String key) {

unparcel();

final Object o = mMap.get(key);

try {

return (String) o;

} catch (ClassCastException e) {

typeWarning(key, o, "String", e);

return null;

}

}

就是直接從Map里面拿出我們之前保存的String,try語句只是在驗證取出的數據是否為String類型。

那照這么分析的話,兩個Activity中的對象應該就是同一個對象才對啊!!為什么又說不是同一個對象呢?

為什么不是同一個對象?

如果你在putExtra之后,馬上又getExtra出來,那么你取出來的對象肯定是同一個對象,這個沒錯!

但是這里我們要注意兩點:

1.Intent中允許保存的數據類型是有限制的,準確的說是Bundle的限制,因為實質上數據是保存在Bundle中。如果我們要保存自己定義的對象,那么我們的對象必須實現了Parcelable接口或者Serializable接口。

2.我們使用Intent的方式,基本都是在一個Activity中存入,然后從另一個Activity中取出。

那么問題很明顯就出在Activity的啟動過程了。詳細的啟動過程大家可以參考老羅的文章Activity啟動過程。

這里大概說一下,首先我們的app運行在app自己的進程appProcess中,然后系統在啟動的時候會啟動一個系統進程systemProcess。而在Activity啟動時,需要向一個叫做ActivityManagerService的系統服務去注冊,這樣我們的Activity才能有生命周期的回調。這個ActivityManagerService服務就運行在systemProcess中。注冊完之后,再回到appProcess中,完成新Activity的啟動。在這個注冊過程中,我們的intent是全程參與的。

說到這里就明白了,當我們調用startActivity(intent)啟動另外的Activity的時候,我們的intent已經完成了兩次跨進程通信,而它里面的對象已經經歷了兩輪序列化和反序列化,肯定不可能是同一個對象了。

這里順便說一個問題:為什么Serializable也可以跨進程傳輸?

熟悉AIDL的同學都很清楚,AIDL跨進程通信支持的數據類型是:

Java 的原生類型,如int,boolean,long,float…

String 和CharSequence

List 和 Map ,List和Map 對象的元素必須是AIDL支持的數據類型

AIDL 自動生成的接口 需要導入(import)

實現android.os.Parcelable 接口的類. 需要導入(import)。

這里并不包括Serializable類型。

于是去看了源碼,發現是Parcel自己對Serializable類型的對象做了兼容,可以直接寫入其中。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

總結

以上是生活随笔為你收集整理的Android底层隐私数据,Android Intent传递数据底层分析详细介绍_Android_脚本之家的全部內容,希望文章能夠幫你解決所遇到的問題。

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