前阵子项目targetSdkVersion从23升级到了26,友盟统计上出现了很多TransactionTooLargeException导致的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及其以下只会有TransactionTooLargeException
的警告,并不会导致crash。 -
targetSdkVersion
在24及其以上会抛出TransactionTooLargeException
导致crash,具体可查看7.0行为变更
许多平台 API 现在开始检查在Binder 事务间发送的大负载,系统现在会将
TransactionTooLargeExceptions
作为RuntimeExceptions
再次引发,而不再只是默默记录或抑制它们。一个常见例子是在[Activity.onSaveInstanceState()](https://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle))
上存储过多数据,导致ActivityThread.StopInfo
在您的应用面向 Android 7.0 时引发RuntimeException
。
二、可能导致该crash的几种情况
虽然可以一眼看出是binder
通讯中传递了过大的数据,但是要定位具体是哪里传递了过大的数据并没有那么容易,这里只把可能发生的情况列举出来:
-
activity或者fragment跳转时,传递的
bundle
携带了过大的数据,比如传递了bitmap
或者size很大的ArrayList
可以借用toolargetool查看。 Activity.onSaveInstanceState()
保存了过大的数据-
FragmentStatePagerAdapter
的saveState
保存了过多的历史Fragment
实例的状态数据,重写saveState
image.png
三、问题解决
第一次迭代中对1和2两种情况做了保护,上线后依然出现TransactionTooLargeException
。
第二次迭代中对3做了处理,再次上线后没有出现TransactionTooLargeException
,问题结局。
thanks:
https://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception
https://www.cnblogs.com/tgltt/p/9834584.html
网友评论