仅在牛轧糖上出现 TransactionTooLargeException
TransactionTooLargeException only on Nougat
我开发了一个应用程序,该应用程序在 Android 版本低于 Nougat 的设备上运行良好。
当我在装有 Nougat 的设备上启动该应用程序并按下主页按钮时,该应用程序崩溃了,在 logcat 我有:
!!! FAILED BINDER TRANSACTION !!! (parcel size = 1819712)
Unhandled exception
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 1819712 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3781)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.os.TransactionTooLargeException: data parcel size 1819712 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:615)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3636)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3773)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
有没有简单的解决办法?此问题仅出现在牛轧糖上。
来自 TransactionTooLargeException
class
的文档
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
您是否检查过要传递的数据大小较低 android API?
我建议您在 android 7.0/7.1 和其他系统上传输数据之前记录此大小。可能在不同的android版本上,你的数据占用的内存量不同。
这里也一样。此问题没有快速解决方案。
我的解决方案是将数据临时存储在数据库或文件中。
也只是在活动和片段之间传输只需要的数据。
我认为对于大多数具有大量数据的用例来说,这也是一种更好的设计模式。
如果 activity 有一些片段并且每个片段都在执行 onSaveInstance,则它会发生更多。如果fragment onCreateView总是重启视图(没有视图状态需要os恢复),那么rootview.setSaveFromParentEnabled(false);以防止视图的 onSaveInstanceState()。这可能会有所帮助。
我也遇到了同样的问题。 google 论坛上的许多开发人员都抱怨过这一点。他们的回答是WAI(work as intended),因为他们不建议在状态下保存太多数据。
所以建议只向 Intent 添加非常基本的参数。
如果要在活动或片段之间发送数据,
- 将数据存储在(临时)文件中并传递文件 URI。
如果您想转移,此选项可能是您唯一的选择
大量数据到一个完全不同的应用程序。存储数据
在应用实例中;
- 创建一个包含
您传递的数据。
如果您使用的是 FragmentStatePageAdapter,请添加以下代码以避免它保存状态数据。
@Override
public Parcelable saveState() {
Bundle bundle = (Bundle) super.saveState();
bundle.putParcelableArray("states", null); // Never maintain any states from the base class to avoid TransactionTooLargeException
return bundle;
}
参考:
https://issuetracker.google.com/issues/37103380
https://www.neotechsoftware.com/blog/android-intent-size-limit
我通过将数据保存到文件中解决了这个问题。谢谢大家的回答。
我开发了一个应用程序,该应用程序在 Android 版本低于 Nougat 的设备上运行良好。
当我在装有 Nougat 的设备上启动该应用程序并按下主页按钮时,该应用程序崩溃了,在 logcat 我有:
!!! FAILED BINDER TRANSACTION !!! (parcel size = 1819712)
Unhandled exception
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 1819712 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3781)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: android.os.TransactionTooLargeException: data parcel size 1819712 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:615)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3636)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3773)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
有没有简单的解决办法?此问题仅出现在牛轧糖上。
来自 TransactionTooLargeException
class
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
您是否检查过要传递的数据大小较低 android API?
我建议您在 android 7.0/7.1 和其他系统上传输数据之前记录此大小。可能在不同的android版本上,你的数据占用的内存量不同。
这里也一样。此问题没有快速解决方案。
我的解决方案是将数据临时存储在数据库或文件中。 也只是在活动和片段之间传输只需要的数据。
我认为对于大多数具有大量数据的用例来说,这也是一种更好的设计模式。
如果 activity 有一些片段并且每个片段都在执行 onSaveInstance,则它会发生更多。如果fragment onCreateView总是重启视图(没有视图状态需要os恢复),那么rootview.setSaveFromParentEnabled(false);以防止视图的 onSaveInstanceState()。这可能会有所帮助。
我也遇到了同样的问题。 google 论坛上的许多开发人员都抱怨过这一点。他们的回答是WAI(work as intended),因为他们不建议在状态下保存太多数据。 所以建议只向 Intent 添加非常基本的参数。 如果要在活动或片段之间发送数据,
- 将数据存储在(临时)文件中并传递文件 URI。 如果您想转移,此选项可能是您唯一的选择 大量数据到一个完全不同的应用程序。存储数据 在应用实例中;
- 创建一个包含 您传递的数据。
如果您使用的是 FragmentStatePageAdapter,请添加以下代码以避免它保存状态数据。
@Override public Parcelable saveState() { Bundle bundle = (Bundle) super.saveState(); bundle.putParcelableArray("states", null); // Never maintain any states from the base class to avoid TransactionTooLargeException return bundle; }
参考:
https://issuetracker.google.com/issues/37103380
https://www.neotechsoftware.com/blog/android-intent-size-limit
我通过将数据保存到文件中解决了这个问题。谢谢大家的回答。