美文网首页
使用toolargetool解决TransactionTooLa

使用toolargetool解决TransactionTooLa

作者: 不思进取的码农 | 来源:发表于2020-12-22 22:54 被阅读0次

BUG分析

android.os.TransactionTooLargeException: data parcel size 1167560 bytes 

一般情况下看到这个BUG都会想到的是Intent传输数据过大了,Intent的数据过大是会导致TransactionTooLargeException的表现,但是如果把这个异常完全归结于Intent就有点问题了,因为TransactionTooLargeException不止会因为Intent传输数据过大了,在某些不是使用Intent的情况下依然会出这样的bug

真的只有Intent传值才会有问题吗,我们通过Intent看问题的本质

Intent携带信息的大小其实是受Binder限制。数据以Parcel对象的形式存放在Binder传递缓存中。如果数据或返回值比传递buffer大,则此次传递调用失败并抛出TransactionTooLargeException异常。

Intent传值最大真的是1MB吗

Binder传递缓存有一个限定大小,通常是1Mb
但同一个进程中所有的传输共享缓存空间。多个地方在进行传输时,即时它们各自传输的数据不超出大小限制,TransactionTooLargeException异常也可能会被抛出。在使用Intent传递数据时,1Mb并不是安全上限。因为Binder中可能正在处理其它的传输工作。不同的机型和系统版本,这个上限值也可能会不同。在其它地方,例如onSaveInstanceState(@NonNull Bundle outState),也可能会遇到与Binder有关的类似问题。

通过toolargetool分析解决TransactionTooLargeException

我们知道了问题的本质是Binder引起的,而引起TransactionTooLargeException不止是在Intent也可能是onSaveInstanceState(@NonNull Bundle outState),特别是onSaveInstanceState其实你没有使用他不代表他本身没有存储,当你遇到一个未知情况引起TransactionTooLargeException的时候,你需求的toolargetool来帮你解决问题

分析工具 toolargetool
地址:https://github.com/guardian/toolargetool
这是专门分析TransactionTooLargeException的工具

(1)增加 maven { url 'https://dl.bintray.com/guardian/android' } 在项目中的build.gradle

allprojects {
    repositories {
        jcenter()
        ...
        maven { url 'https://dl.bintray.com/guardian/android' }
    }
}

(2)增加 implementation 'com.gu.android:toolargetool:0.2.1@aar' 在你检测问题 module下的build.gradle:

dependencies {
    ...
    implementation 'com.gu.android:toolargetool:0.2.1@aar'
    //implementation 'com.gu.android:toolargetool:0.1.6@aar' // if you don't use AndroidX in your project
}

(3)在Application.onCreate方法里面增加

TooLargeTool.startLogging(this);

(4)在你要检查的类里面引入package

import com.gu.toolargetool.TooLargeTool;

(5)监视logcat输出,查看哪些组件正在向事务缓冲区写入大量数据以及何时写入

可以使用命令进行过滤:

$ adb logcat -s TooLargeTool

最终我们的过滤日志发现


12-02 16:35:33.087 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle131394213 contains 5 keys and measures 19.0 KB when serialized as a Parcel
12-02 16:35:33.087 16961 16961 D TooLargeTool: * android:viewHierarchyState = 1.0 KB

12-02 16:35:52.402 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle140574781 contains 5 keys and measures 57.8 KB when serialized as a Parcel
12-02 16:35:52.402 16961 16961 D TooLargeTool: * android:viewHierarchyState = 14.2 KB

12-02 16:36:23.626 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle216803432 contains 5 keys and measures 83.2 KB when serialized as a Parcel
12-02 16:36:23.626 16961 16961 D TooLargeTool: * android:viewHierarchyState = 37.2 KB

12-02 16:37:12.587 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle91071570 contains 5 keys and measures 118.5 KB when serialized as a Parcel
12-02 16:37:12.587 16961 16961 D TooLargeTool: * android:viewHierarchyState = 76.1 KB

12-02 16:37:37.113 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle45092331 contains 5 keys and measures 166.8 KB when serialized as a Parcel
12-02 16:37:37.113 16961 16961 D TooLargeTool: * android:viewHierarchyState = 122.2 KB

12-02 16:39:31.786 16961 16961 D TooLargeTool: LivePlayerPageActivity.onSaveInstanceState wrote: Bundle267655365 contains 5 keys and measures 202.2 KB when serialized as a Parcel
12-02 16:39:31.786 16961 16961 D TooLargeTool: * android:viewHierarchyState = 159.7 KB


这问题是使用ViewPager2实现纵滑直播间,在特定情况下出现的TransactionTooLargeException,在特定下情况再次滑动直播间android:viewHierarchyState 的值一直是增加的最终导致超限引起TransactionTooLargeException

既然知道问题所在了,但是我没有找到为什么viewHierarchyState会一直增加,源码中对这个方法也没有描述,不知其含义 所以我们选择了一种无可奈何的解决办法让ViewPager2不再保存
在xml中增加android:saveEnabled="false",这不是一个最完美的办法 但是目前在一个未知问题下是解决我们现在问题的一种方式,因为我们的页面不涉及横竖屏切换这样的操作.

    <androidx.viewpager2.widget.ViewPager2
        android:id="@+id/viewpager2"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:saveEnabled="false" />

(每天学习一点点.每天进步一点点,分享不宜路过点个赞呀,喜欢的点个关注后续更新不断)

相关文章

网友评论

      本文标题:使用toolargetool解决TransactionTooLa

      本文链接:https://www.haomeiwen.com/subject/jxshgktx.html