Android 12/13中Could not copy bitmap to parcel blob崩溃问题解决
问题:Android 12+中Bitmap转文件后跳转Activity崩溃
我将Bitmap转换为文件并发送至服务器,响应成功后跳转至另一个Activity,该操作在Android 11中正常运行,但在Android 12/13等新版本中崩溃。若不执行跳转则无异常。
崩溃日志
E FATAL EXCEPTION: main Process: com.docmobil.client, PID: 10829 java.lang.RuntimeException: Could not copy bitmap to parcel blob. at android.graphics.Bitmap.nativeWriteToParcel(Native Method) at android.graphics.Bitmap.writeToParcel(Bitmap.java:2140) at android.os.Parcel.writeParcelable(Parcel.java:2538) at android.os.Parcel.writeValue(Parcel.java:2439) at android.os.Parcel.writeValue(Parcel.java:2316) at android.os.Parcel.writeArrayMapInternal(Parcel.java:1265) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1802) at android.os.Bundle.writeToParcel(Bundle.java:1389) at android.os.Parcel.writeBundle(Parcel.java:1334) at android.os.Parcel.writeValue(Parcel.java:2433) at android.os.Parcel.writeValue(Parcel.java:2323) at android.os.Parcel.writeSparseArray(Parcel.java:1422) at android.os.Parcel.writeValue(Parcel.java:2463) at android.os.Parcel.writeValue(Parcel.java:2316) at android.os.Parcel.writeArrayMapInternal(Parcel.java:1265) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1802) at android.os.Bundle.writeToParcel(Bundle.java:1389) at android.os.Parcel.writeBundle(Parcel.java:1334) at android.os.Parcel.writeValue(Parcel.java:2433) at android.os.Parcel.writeValue(Parcel.java:2323) at android.os.Parcel.writeArrayMapInternal(Parcel.java:1265) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1802) at android.os.Bundle.writeToParcel(Bundle.java:1389) at android.os.Parcel.writeTypedObject(Parcel.java:2157) at android.app.IActivityClientController$Stub$Proxy.activityStopped(IActivityClientController.java:1277) at android.app.ActivityClient.activityStopped(ActivityClient.java:86) at android.app.servertransaction.PendingTransactionActions$StopInfo.run(PendingTransactionActions.java:143) at android.os.Handler.handleCallback(Handler.java:942) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loopOnce(Looper.java:201) at android.os.Looper.loop(Looper.java:288) at android.app.ActivityThread.main(ActivityThread.java:7872) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
相关代码
@Throws(IOException::class) private fun convertBitmapToFile(bitmap: Bitmap): File { val wrapper = ContextWrapper(this) var file = wrapper.getDir("Images", Context.MODE_PRIVATE) file = File(file, "${userName}_signature.jpg") val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream) val stream: OutputStream = FileOutputStream(file) stream.flush() stream.close() val i = Intent(this@DisclosureActivity, DoctorInfoAct::class.java) startActivity(i) return file }
问题原因
Android 12(API 31)收紧了Activity状态保存时的Parcel Blob大小限制。跳转Activity时,系统会触发原Activity的onSaveInstanceState流程,如果当前Activity持有未回收的大Bitmap对象,系统会尝试将其序列化写入Parcel,超过Blob大小上限后抛出崩溃。
解决方案
1. 及时回收Bitmap资源
在跳转Activity前,主动回收Bitmap并释放引用,避免系统序列化该对象:
@Throws(IOException::class) private fun convertBitmapToFile(bitmap: Bitmap): File { val wrapper = ContextWrapper(this) var file = wrapper.getDir("Images", Context.MODE_PRIVATE) file = File(file, "${userName}_signature.jpg") val byteArrayOutputStream = ByteArrayOutputStream() bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream) val stream: OutputStream = FileOutputStream(file) // 补充写入字节流到文件(原代码遗漏此步骤,会导致生成空文件) stream.write(byteArrayOutputStream.toByteArray()) stream.flush() stream.close() // 回收Bitmap资源 bitmap.recycle() // 若有全局Bitmap引用,需同时置为null,例如:mSignatureBitmap = null val i = Intent(this@DisclosureActivity, DoctorInfoAct::class.java) startActivity(i) return file }
2. 避免Activity持有大Bitmap强引用
如果Bitmap是Activity的成员变量,在跳转前将其置为null,让GC能及时回收该对象,避免被序列化到Parcel中。
3. 使用ViewModel存储Bitmap(如需保留)
若后续还需使用Bitmap,不要直接在Activity中持有,而是将其放在ViewModel里。ViewModel不会在Activity状态保存时被序列化,可绕过Parcel大小限制。
内容的提问来源于stack exchange,提问作者Jaydip Chavda
相关产品推荐
相关产品推荐

