仅在Nougat上的TransactionTooLargeException

时间:2017-04-18 07:42:29

标签: android android-7.0-nougat parcel android-7.1-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) 

有简单的解决方案吗?此问题仅出现在Nougat上。

5 个答案:

答案 0 :(得分:6)

我有同样的问题。谷歌论坛上的许多开发者都抱怨这一点。他们的答案是WAI(按预期工作),因为他们不建议在州内保存太多数据。 所以建议只向Intent添加非常基本的参数。 如果要在活动或片段之间发送数据,

  • 将数据存储在(临时)文件中并传递文件URI。 如果您想转移,此选项可能是您唯一的选择 大量数据到完全不同的应用程序。存储数据 在Application实例中;
  • 创建一个包含。的单例容器 你传递的数据。
  • 如果您使用的是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

答案 1 :(得分:1)

来自TransactionTooLargeException

的文档
  

Binder事务缓冲区具有有限的固定大小,当前 1Mb ,由进程正在进行的所有事务共享。因此,即使大多数单个事务的大小适中,当有许多事务正在进行时,也会抛出此异常。

您是否检查了在较低的android API上传递的数据大小?

我建议在Android 7.0 / 7.1和其他设备上传输数据之前记录此大小。可能在不同的Android版本上,您的数据占用不同的内存量。

答案 2 :(得分:0)

同样在这里。没有快速解决此问题的方法。

我的解决方案是将数据临时存储在数据库中。 同样只是在活动和片段之间仅发送所需的数据。

我认为对于大多数具有大量数据的用户来说,这也是一种更好的设计模式。

答案 3 :(得分:0)

如果有一些带有活动的片段并且每个片段都在执行onSaveInstance,那么它会发生更多。如果片段onCreateView总是重启视图(没有视图状态需要os来恢复),那么rootview.setSaveFromParentEnabled(false);防止查看onSaveInstanceState()。这可能会有所帮助。

答案 4 :(得分:0)

我通过在文件中保存数据解决了这个问题。谢谢你的所有答案。