android.os.TransactionTooLargeException解决方案,Kotlin
首先,特意制造一个让Android发生TransactionTooLargeException的场景,一个Activity启动另外一个Activity,在Intent的Bundle里面塞入一个大的ArrayList:
import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.nio.charset.Charsetclass MainActivity : AppCompatActivity() {companion object {const val MY_KEY = "my_key"const val MY_BUNDLE = "my_bundle"}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val ctx = thisCoroutineScope(Dispatchers.IO).launch {val bytes = "z".toByteArray(Charset.defaultCharset())val count = 1024 * 1024val list = arrayListOf<ByteArray>()for (i in 0..count) {list.add(bytes)}val bundle = Bundle()bundle.putSerializable(MY_KEY, list)CoroutineScope(Dispatchers.Main).launch {val intent = Intent(ctx, MyTestActivity::class.java)intent.putExtra(MY_BUNDLE, bundle)startActivity(intent)}}}
}
被启动的MyTestActivity:
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivityclass MyTestActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val bundle = intent.getBundleExtra(MainActivity.MY_BUNDLE)Log.d("fly", "MyTestActivity onCreate size=${bundle?.getSerializable(MainActivity.MY_KEY, ArrayList::class.java)?.size}")}
}
MainActivity运行起来后,应用直接崩溃抛错:
!!! FAILED BINDER TRANSACTION !!! (parcel size = 12583376)
Caused by: android.os.TransactionTooLargeException: data parcel size 12583376 bytes
因为Bundle传输的数据总量大小不能超过1MB,且应用内的Activity/Frgment共享这1MB。
解决方案
两边改造,换用Binder,参考( Android Bundle putBinder传输超过1MB数据,Kotlin-CSDN博客 ):
import android.content.Intent
import android.os.Binder
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.nio.charset.Charsetclass MainActivity : AppCompatActivity() {companion object {const val MY_KEY = "my_key"const val MY_BUNDLE = "my_bundle"}override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val ctx = thisCoroutineScope(Dispatchers.IO).launch {val bytes = "z".toByteArray(Charset.defaultCharset())val count = 1024 * 1024val list = arrayListOf<ByteArray>()for (i in 0..count) {list.add(bytes)}val bundle = Bundle()bundle.putBinder(MY_KEY, MyBinder(list))CoroutineScope(Dispatchers.Main).launch {val intent = Intent(ctx, MyTestActivity::class.java)intent.putExtra(MY_BUNDLE, bundle)startActivity(intent)}}}
}class MyBinder : Binder {private var data: ArrayList<ByteArray>? = nullconstructor(data: ArrayList<ByteArray>?) {this.data = data}fun getData(): ArrayList<ByteArray>? {return data}
}
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivityclass MyTestActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val bundle = intent.getBundleExtra(MainActivity.MY_BUNDLE)val binder = bundle?.getBinder(MainActivity.MY_KEY) as MyBinderLog.d("fly", "MyTestActivity onCreate size=${binder.getData()?.size}")}
}
MainActivity启动后,MyTestActivity成功收到通过Bundle传输的超大数据集:
Android TransactionTooLargeException排查定位-CSDN博客文章浏览阅读724次,点赞10次,收藏20次。文章浏览阅读422次。文章浏览阅读5.5k次。本文作者:Zhang Phil原文链接:Android Activity生命周期以及onSaveInstanceState、onRestoreInstanceState要点备忘一般的,当Android activity的生命周期进入onPause后,Android系统紧接着就要回调:protected void onSaveInstanceState_activity生命周期 onsaveinstane。https://blog.csdn.net/zhangphil/article/details/136745278