當前位置:編程學習大全網 - 熱門推薦 - Intent數據大小限制及TransactionTooLargeException異常

Intent數據大小限制及TransactionTooLargeException異常

崩潰日誌:

雖說壹眼就看出是binder通訊引發的崩潰,但就如同OOM問題,定性問題容易,但定位問題卻不容易。

官方說明:

1. TransactionTooLargeException

簡單來說:壹個應用進程的所有 AIDL 調用都是***用壹個 Binder transaction buffer,而這個 buffer 的大小僅僅只是 1Mb,當所有的遠程調用的參數或者這些調用返回值的大小加起來超過 1Mb 的話就會拋出 TransactionTooLargeException 異常。

2. Parcelables and Bundles

Binder 傳輸緩沖區是壹個限制的大小的區域,大小為 1MB,這塊緩沖區用於所有進程間的通信,也就是 Binder 通信。這些傳輸包括 onSaveInstanceState , startActivity 和其他與系統的交互,當傳輸的數據超過這個大小的時候就會拋出異常。

特別是 onSaveInstanceState 方法,因其需要在 Activity 返回的時候提供數據,官網建議是數據大小不大於 50K.

註意:

1.是不是只要通過 Bundle 傳遞數據,就會面臨序列化的問題?

並不是,Activity 之間傳遞數據,首先要考慮跨進程的問題,而 Android 中又是通過 Binder 機制來解決跨進程通信的問題。涉及到跨進程,對於復雜數據就要涉及到序列化和反序列化的過程,這就註定是壹次值傳遞(深拷貝)的過程。

Fragment 本身是不涉及跨進程的,這裏雖然使用了 Bundle 傳輸數據,但是並沒有通過 Binder,也就是不存在序列化和反序列化。和 Fragment 數據傳遞相關的 Bundle,其實傳遞的是原對象的引用。

結論:通過Fragment 的setArguments(Bundle) 傳遞壹個 Bundle ,這裏雖然使用了 Bundle 傳輸數據,但是並沒有通過 Binder,也就是不存在序列化和反序列化。和 Fragment 數據傳遞相關的 Bundle,其實傳遞的是原對象的引用。(做個試驗,彈出 DialogFragment 時傳遞壹個對象,Dialog 中修改數據後,在 Activity 中該對象被修改了)

2.Activity onSaveInstanceState 中保存的 Bundle 信息是存在內存中的,且因為是涉及到 Activity 的狀態的保存,就需要交由 ActivityManager 進程去做壹個管理,所以就需要 Binder 傳輸做壹個跨進程的通信將 Bundle 的數據傳遞給 ActivityManager。因此 onSaveInstanceState 也涉及到了 Binder 傳輸,自然而然就受到 Binder 緩沖區大小的限制.

3.FragmentStatePagerAdapter的實現有缺陷,因為其默認實現會持續保存歷史Fragment實例的狀態數據歷史,在逐漸地積累、保存數據後,最終導致發送的數據包體積超過限制50KB

/mmbiz_jpg/liaczD18OicSz3ctQsLW8lGAAMWev0a16PZoqAev5CViaTTBuUZrWNG1m27sIicfKrYZicMmjdP4WwFO53vicWToC3Ag/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

使用EventBus postSticky()方法發送,它會將事件緩存到 stickyEvents 這個 Map 對象中,以待下次註冊時,將這個事件取出,拋給註冊的組件。

接收:

參考鏈接:

面試常客:Intent 能傳遞多大 Size 的數據?| 付阿裏的建議方案!

Android----onSaveInstanceState 的數據存在哪裏?為什麽限制了大小?

TransactionTooLargeException原因分析

  • 上一篇:雲頂之弈拼多多小法怎麽克制
  • 下一篇:什麽是psp 盟卡
  • copyright 2024編程學習大全網