前陣子項(xiàng)目targetSdkVersion從23升級(jí)到了26,友盟統(tǒng)計(jì)上出現(xiàn)了很多TransactionTooLargeException導(dǎo)致的crash,日志如下
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 579328 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3873)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:165)
at android.app.ActivityThread.main(ActivityThread.java:6375)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
Caused by: android.os.TransactionTooLargeException: data parcel size 579328 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:622)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3688)
at java.lang.reflect.Method.invoke(Native Method)
at com.morgoo.droidplugin.hook.proxy.ProxyHook.invoke(ProxyHook.java:62)
at com.morgoo.droidplugin.hook.proxy.IActivityManagerHook.invoke(IActivityManagerHook.java:63)
at java.lang.reflect.Proxy.invoke(Proxy.java:813)
at $Proxy25.activityStopped(Unknown Source)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3865)
... 7 more
android.os.TransactionTooLargeException: data parcel size 579328 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:622)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3688)
at java.lang.reflect.Method.invoke(Native Method)
at com.morgoo.droidplugin.hook.proxy.ProxyHook.invoke(ProxyHook.java:62)
at com.morgoo.droidplugin.hook.proxy.IActivityManagerHook.invoke(IActivityManagerHook.java:63)
at java.lang.reflect.Proxy.invoke(Proxy.java:813)
at $Proxy25.activityStopped(Unknown Source)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3865)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:165)
at android.app.ActivityThread.main(ActivityThread.java:6375)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:802)
一、原因分析:
targetSdkVersion在23及其以下只會(huì)有TransactionTooLargeException的警告,并不會(huì)導(dǎo)致crash。targetSdkVersion在24及其以上會(huì)拋出TransactionTooLargeException導(dǎo)致crash,具體可查看7.0行為變更
許多平臺(tái) API 現(xiàn)在開(kāi)始檢查在Binder 事務(wù)間發(fā)送的大負(fù)載,系統(tǒng)現(xiàn)在會(huì)將
TransactionTooLargeExceptions作為RuntimeExceptions再次引發(fā),而不再只是默默記錄或抑制它們。一個(gè)常見(jiàn)例子是在[Activity.onSaveInstanceState()](https://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle))上存儲(chǔ)過(guò)多數(shù)據(jù),導(dǎo)致ActivityThread.StopInfo在您的應(yīng)用面向 Android 7.0 時(shí)引發(fā)RuntimeException。
二、可能導(dǎo)致該crash的幾種情況
雖然可以一眼看出是binder通訊中傳遞了過(guò)大的數(shù)據(jù),但是要定位具體是哪里傳遞了過(guò)大的數(shù)據(jù)并沒(méi)有那么容易,這里只把可能發(fā)生的情況列舉出來(lái):
-
activity或者fragment跳轉(zhuǎn)時(shí),傳遞的
bundle攜帶了過(guò)大的數(shù)據(jù),比如傳遞了bitmap或者size很大的ArrayList
可以借用toolargetool查看。 Activity.onSaveInstanceState()保存了過(guò)大的數(shù)據(jù)-
FragmentStatePagerAdapter的saveState保存了過(guò)多的歷史Fragment實(shí)例的狀態(tài)數(shù)據(jù),重寫saveState
image.png
三、問(wèn)題解決
第一次迭代中對(duì)1和2兩種情況做了保護(hù),上線后依然出現(xiàn)TransactionTooLargeException。
第二次迭代中對(duì)3做了處理,再次上線后沒(méi)有出現(xiàn)TransactionTooLargeException,問(wèn)題結(jié)局。
thanks:
https://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception
https://www.cnblogs.com/tgltt/p/9834584.html
