Android Bundle putBinder传输超过1MB数据,Kotlin
由于Android系统架构的设计,Activity/Fragment之间通过Intent在Bundle塞进数据进行传输时候,如果数据超过1MB,会抛JE:
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size xxxxxxx bytes
关于TransactionTooLargeException:
The Binder transaction failed because it was too large. During a remote procedure call, the arguments and the return value of the call are transferred as Parcel objects stored in the Binder transaction buffer. If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown. The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process. Consequently this exception can be thrown when there are many transactions in progress even when most of the individual transactions are of moderate size.
但是新版Android系统可用通过在Bundle里面的putBinder传输超过1MB的数据,甚至直接可用传递更大的Bitmap:
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Binder
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class MainActivity : AppCompatActivity() {
private val TAG = "fly"
private val KEY = "key"
private var mBitmap: Bitmap? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Log.d(TAG, "onCreate savedInstanceState=${savedInstanceState?.size()}")
val bmp = (savedInstanceState?.getBinder(KEY) as? MyBinder)?.getBitmap()
if (bmp != null) {
Log.d(TAG, "onCreate bmp != null bmp=${bmp.byteCount}")
mBitmap = bmp
} else {
lifecycleScope.launch(Dispatchers.IO) {
mBitmap = BitmapFactory.decodeResource(resources, R.mipmap.p4m)
Log.d(TAG, "mBitmap=${mBitmap?.byteCount}")
}
}
}
override fun onDestroy() {
super.onDestroy()
Log.d(TAG, "onDestroy")
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
Log.d(TAG, "onSaveInstanceState outState=${outState.size()}")
outState.putBinder(KEY, MyBinder(mBitmap!!))
Log.d(TAG, "onSaveInstanceState putBinder outState=${outState.size()}")
}
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
Log.d(TAG, "onRestoreInstanceState outState=${savedInstanceState.size()}")
val bmp = (savedInstanceState.getBinder(KEY) as? MyBinder)?.getBitmap()
Log.d(TAG, "onRestoreInstanceState bmp=${bmp?.byteCount}")
}
class MyBinder : Binder {
private var bitmap: Bitmap? = null
constructor(bmp: Bitmap) {
this.bitmap = bmp
}
fun getBitmap(): Bitmap? {
return bitmap
}
}
}
Activity启动后:
当切换黑夜模式/深色主题后,当前Activity消耗重建,但Bundle数据会被存储和传输:
而如果在onCreate()里面,清除Bundle,那么就不会再有累积的数据:
savedInstanceState?.clear()
Android切换主题生命周期流程与onSaveInstanceState和onRestoreInstanceState,Kotlin_安卓开发系统切换主题 重走生命周期-CSDN博客文章浏览阅读422次。本文作者:Zhang Phil原文链接:Android Activity生命周期以及onSaveInstanceState、onRestoreInstanceState要点备忘一般的,当Android activity的生命周期进入onPause后,Android系统紧接着就要回调:protected void onSaveInstanceState。Android Fragment生命周期图以及Activity与Fragment生命周期对照图-CSDN博客。_安卓开发系统切换主题 重走生命周期https://blog.csdn.net/zhangphil/article/details/133943450Android Activity生命周期以及onSaveInstanceState、onRestoreInstanceState要点备忘_activity生命周期 onsaveinstane-CSDN博客文章浏览阅读5.5k次。本文作者:Zhang Phil原文链接:Android Activity生命周期以及onSaveInstanceState、onRestoreInstanceState要点备忘一般的,当Android activity的生命周期进入onPause后,Android系统紧接着就要回调:protected void onSaveInstanceState_activity生命周期 onsaveinstanehttps://blog.csdn.net/zhangphil/article/details/48155371