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.Charset
class 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 = this
CoroutineScope(Dispatchers.IO).launch {
val bytes = "z".toByteArray(Charset.defaultCharset())
val count = 1024 * 1024
val 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.AppCompatActivity
class 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.Charset
class 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 = this
CoroutineScope(Dispatchers.IO).launch {
val bytes = "z".toByteArray(Charset.defaultCharset())
val count = 1024 * 1024
val 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>? = null
constructor(data: ArrayList<ByteArray>?) {
this.data = data
}
fun getData(): ArrayList<ByteArray>? {
return data
}
}
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
class 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 MyBinder
Log.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