You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:54:58