如何在Android不同Activity间传输Bitmap?(Camera2 API捕获场景)
Bitmap在Android不同Activity间传输的完整实现
没问题,我给你整理了完整的实现方案,包括发送端、接收端的代码,还有需要注意的细节:
发送端(捕获图像的Activity)
你已经有了Bitmap转字节数组的基础代码,这里补充完整的跳转逻辑:
// 从TextureView获取捕获到的Bitmap Bitmap bitmap = textureView.getBitmap(); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); // 将Bitmap压缩为JPEG格式,第二个参数是质量(0-100,数值越高质量越好、体积越大) bitmap.compress(Bitmap.CompressFormat.JPEG, 100, byteStream); byte[] bitmapBytes = byteStream.toByteArray(); // 创建Intent,指定要跳转的目标Activity(比如确认保存的页面) Intent intent = new Intent(this, ConfirmSaveActivity.class); // 将字节数组存入Intent的Extra中,注意键名要和接收端对应 intent.putExtra("KEY_BITMAP_BYTES", bitmapBytes); // 启动目标Activity startActivity(intent); // 可选:如果发送端不再需要这个Bitmap,及时回收内存 if (!bitmap.isRecycled()) { bitmap.recycle(); }
接收端(确认保存的Activity)
这里实现从Intent中取出字节数组并转回Bitmap,再添加保存逻辑:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_confirm_save); // 从Intent中获取字节数组 byte[] receivedBytes = getIntent().getByteArrayExtra("KEY_BITMAP_BYTES"); if (receivedBytes != null) { // 将字节数组解码为Bitmap Bitmap receivedBitmap = BitmapFactory.decodeByteArray(receivedBytes, 0, receivedBytes.length); // 示例:把Bitmap显示到预览ImageView ImageView previewImg = findViewById(R.id.iv_preview); previewImg.setImageBitmap(receivedBitmap); // 保存按钮的点击事件 Button saveBtn = findViewById(R.id.btn_save); saveBtn.setOnClickListener(v -> saveCapturedBitmap(receivedBitmap)); } } // 保存Bitmap到本地的工具方法 private void saveCapturedBitmap(Bitmap bitmap) { // Android 10及以上推荐用MediaStore,这里以外部私有目录为例(无需额外权限) File saveDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); if (saveDir == null) { Toast.makeText(this, "存储目录不可用", Toast.LENGTH_SHORT).show(); return; } // 生成唯一文件名 String fileName = "captured_" + System.currentTimeMillis() + ".jpg"; File saveFile = new File(saveDir, fileName); try (FileOutputStream fos = new FileOutputStream(saveFile)) { // 再次压缩保存(可以调整质量) bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); // 通知系统媒体库更新,让图片能在相册中显示 MediaScannerConnection.scanFile(this, new String[]{saveFile.getAbsolutePath()}, null, null); Toast.makeText(this, "图片保存成功", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); Toast.makeText(this, "保存失败", Toast.LENGTH_SHORT).show(); } }
关键注意事项
- Intent传输大小限制:Android的Intent Extra有默认大小限制(通常在1MB左右),如果你的Bitmap分辨率很高(比如4K),直接传字节数组可能会触发
TransactionTooLargeException。遇到这种情况可以换两种方案:- 把Bitmap临时存在Application类的全局变量中(记得用完后及时置空,避免内存泄漏)
- 捕获后先写入临时文件,只传递文件路径,确认保存后再保留文件,取消则删除临时文件
- 内存优化:Bitmap很占内存,传输完成后,在不需要的地方及时调用
bitmap.recycle()释放内存,同时避免重复创建Bitmap对象 - 压缩策略:如果对图片质量要求不高,可以降低compress方法的质量参数(比如80),大幅减少字节数组的体积,提升传输效率
内容的提问来源于stack exchange,提问作者chang gyu
相关产品推荐
相关产品推荐

