關於Intent

我可能是一隻假程式猿發表於2019-05-06

是什麼?

在Android中利用Intent在各個元件間通訊。

傳值方法:

  • intent.putExtra();
基本型別:
String     byte    short    int    long     char     boolean     float     double
String[]   byte[]  short[]  int[]  long[]   char[]   boolean[]   float[]   double[]
序列化: 
Parcelable     CharSequence     Serializable
Parcelable[]   CharSequence[]
複製程式碼
  • intent.putCharSequenceArrayListExtra();

  • intent.putIntegerArrayListExtra();

  • intent.putStringArrayListExtra();

  • intent.putParcelableArrayListExtra();

  • intent.putExtras(); 傳遞一個bundle物件,所有資料都封裝在bundle中

思考一:Intent最大傳遞資料有限制嗎? 限制是多少?

  • 測試案例:用intent傳遞 1M 的byte陣列
Intent intent = new Intent(AActivity.this, BActivity.class);
byte[] bytes = new byte[1024 * 1024];
intent.putExtra("key", bytes);
startActivity(intent);
複製程式碼
  • 結果:報異常 TransactionTooLargeException
 Caused by: android.os.TransactionTooLargeException: data parcel size 1048956 bytes
        at android.os.BinderProxy.transactNative(Native Method)
        at android.os.BinderProxy.transact(Binder.java:615)
        at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3070)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1518)
複製程式碼

思考二:如果有限制,有什麼好的傳輸方案嗎?

  • 可採用EventBus等類似方案傳遞資料;

  • 可宣告靜態變數來進行資料傳遞;「效率高,耦合性高」

  • 可將資料先持久化再還原,可利用SharedPreferences 或 存入資料庫 ,sp相對簡單;「效率低」

    //將物件轉換為 json字串,使用sp儲存
    Gson gson = new GsonBuilder().serializeNulls().create();
    String json = gson.toJson(userEntity);
    
    //通過json字串取出 ,轉為物件
    Gson gson = new GsonBuilder().serializeNulls().create();
    UserEntity loginUser = gson.fromJson(jsonEntity,UserEntity.class);
複製程式碼

思考三:Intent 使用 Bundle 儲存資料,到底是值傳遞(深拷貝)還是引用傳遞?

  • Intent傳值型別要求:

    1)Intent 傳輸的資料,都存放在一個 Bundle 型別的物件 mExtras 中,Bundle 要求所有儲存的資料,都是可被序列化的。

    2)為什麼這裡的Bundle要求傳遞的資料必須序列化?

    因為 Activity 之間傳遞資料,首先要考慮跨程式的問題,而Android中又是通過 Binder機制來解決跨程式通訊的問題。涉及到跨程式,對於複雜資料就要涉及到序列化和反序列化的過程,這就註定是一次值傳遞(深拷貝)的過程。

    3)所有通過Bundle傳遞資料都需要序列化嗎?

    不是,這裡的序列化只與Binder的跨程式通訊有關,其他例如Fragment傳值用到的Bundle不需要序列化。

  • 序列化說明:

    在 Android 中,序列化資料需要實現Serializable或者Parcelable。對於基礎資料型別的包裝類,本身就是實現了Serializable,而我們自定義的物件,按需實現這兩個序列化介面的其中一個即可。

  • 所以這個問題用反證法也可以解釋,如果是引用傳遞,那傳遞過去的只是物件的引用,指向了物件的儲存地址,就只相當於一個Int的大小,也就根本不會出現TransactionTooLargeException異常。

思考四:intent與bundle的序列化和反序列化規則?

思考五:序列化和反序列化的關鍵點是什麼?

感謝

面試常客:Intent 能傳遞多大 Size 的資料?| 付阿里的建議方案!

學Android 這麼久,intent傳遞資料最大多少呢?

intent傳遞資料太大,報TransactionTooLargeException異常

相關文章