【问题标题】:Is there any limit of bundle in Android?Android中的捆绑包有限制吗?
【发布时间】:2011-12-18 14:53:22
【问题描述】:

我想知道android bundle的数据大小是否有上限。我尝试通过大小 >80k 的捆绑包发布数据,并抛出 android 致命异常。数据是可序列化的。

【问题讨论】:

    标签: android limit bundle


    【解决方案1】:

    这取决于捆绑的目的。捆绑包本身仅受内存量的限制。

    bundle 的两个主要用途是使用意图在组件之间传递信息以及保存活动的状态。

    1。意图/粘合剂

    当用于在 Android 组件之间传递信息时,bundle 被序列化为一个 binder 事务。一个进程中所有 binder 事务的总大小为 1MB。如果超出此限制,您将收到此致命错误“!!! FAILED BINDER TRANSACTION !!!”

    建议您将这些捆绑包中的数据尽可能小,因为它是一个共享缓冲区,任何超过几千字节的数据都应该写入磁盘。

    参考:https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/jni/android_util_Binder.cpp

    ALOGE("!!! FAILED BINDER TRANSACTION !!!");
            // TransactionTooLargeException is a checked exception, only throw from certain methods.
            // FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
            //        but it is not the only one.  The Binder driver can return BR_FAILED_REPLY
            //        for other reasons also, such as if the transaction is malformed or
            //        refers to an FD that has been closed.  We should change the driver
            //        to enable us to distinguish these cases in the future.
    

    参考:http://developer.android.com/reference/android/os/TransactionTooLargeException.html

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

    2。已保存的实例状态(Activity onSaveInstanceState、onPause 等)

    我发现用于保存 Activity 状态的包中可以存储的大小没有限制。在我收到内存不足异常尝试分配我试图保存的数据之前,我做了一些测试并且可以成功存储大约 175mb。

    更新:这项研究是在 2014 年进行的,较新版本的 Android 可能会在捆绑包超过 500kb 时崩溃

    【讨论】:

    • 我对您在“保存的实例状态”上所做的测试很感兴趣。当我将一个巨大的字符串放入 onSaveInstateState() 内的包中时,我在 Logcat 中收到“FAILED BINDER TRANSACTION”错误。看来数据已正确保存和恢复。唯一的问题是我在日志中遇到了上述错误,如果这在某些设备/api 版本上会失败,这会让我感到困扰。当您成功存储 175mb 时,您是否得到了错误?
    • 2 在 7.0+ 上不正确。见底部附近的developer.android.com/about/versions/nougat/…
    • @yongsunCN 175MB 的说法是错误的。在 Android 7.0+ (Nougat) 上,当捆绑包的大小超过限制(现在接近 175MB,但大约为 0.5MB)时会引发异常。以前的版本仅记录警告,但从该版本开始会引发异常。
    【解决方案2】:

    我认为限制是 500kb。 您可以将传递的对象保存在文件中,并在包中发送文件的路径。 您可以在SO查看我提出的类似问题

    【讨论】:

    • 你有那个号码的参考吗?
    • 在那次讨论中,您会看到几个数字(500kb 和 1mb),其中后一个是自称“Dianne Hackborn Android 框架工程师”的人,所以如果你想从那个线程中获得一个数字,我会选那个吗?此外,我不太确定那里的主题是“捆绑数据”
    • 我认为 hackbod 评论与 binder rpc 相关,而不是 bundle。
    • Bundle 本身既不能限制它持有的数据,也不知道它持有多少。 Binder 事务限制数据大小。
    【解决方案3】:

    Binder 事务缓冲区有一个有限的固定大小,目前 1MB,由进程中所有正在进行的事务共享。由于此限制是在进程级别而不是在每个活动级别,因此这些事务包括应用程序中的所有绑定事务,例如 onSaveInstanceState、startActivity 以及与系统的任何交互。当超出大小限制时,会抛出 TransactionTooLargeException。

    对于 savedInstanceState 的特定情况,数据量应该保持较小,因为只要用户可以导航回该活动,系统进程就需要保留提供的数据(即使活动的进程是被杀)。我们建议将保存状态保持在少于 50k 的数据。

    Parcelable and Bundles

    【讨论】:

      【解决方案4】:

      是的,现在在 android Nougat 中,如果您大致超过限制 (500Kb),它将崩溃。

      android nougat issue

      【讨论】:

        【解决方案5】:

        根据Google Android API,日期应该小于50K。

        【讨论】:

        • '我们建议您将保存状态保持在少于 50k 的数据。'这不是限制,这是建议。
        【解决方案6】:

        是的,它有 1MB 的限制。

        你可以使用Singleton类来传递数据。

        【讨论】:

        • Singleton 类无法在应用重新启动后继续存在。 Android 操作系统可以重新启动您的应用程序并尝试继续使用已保存的实例和意图包。这会在返回在后台停留时间过长的应用程序时导致 nullpointerexception。 developerphil.com/dont-store-data-in-the-application-object
        • 单例类仅用于在活动或片段之间传递数据
        • 单例类的正确实现,使用@fthdgn就可以了
        【解决方案7】:

        我认为最大包大小为 1024 千字节。为了在活动之间传输大对象,您应该尝试其他方式(内存缓存、本地存储等)。

        【讨论】:

        • 1024 什么?你有参考吗?
        • 1024 字节。我想我已经在某处读过它,并且还尝试了更多代码并得到了致命的。如果我发现任何更具体的内容,我会告诉你。
        • 你不会得到致命的,数据在你收到时似乎是随机的(n4 4.2.2)。
        • 这是错误的,1024 字节太少了 :) 实际限制应该是 1MB,但大多数时候会更少,请参阅这篇文章了解更多详情nemanjakovacevic.net/blog/english/2015/03/24/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-15
        • 1970-01-01
        • 2014-01-08
        • 2021-02-26
        • 1970-01-01
        相关资源
        最近更新 更多