CameraX PreviewView直接生成Bitmap传递到其他Activity空指针问题求助
错误根因
你遇到的崩溃并非viewFinder.bitmap为空导致,核心问题是你在VirtualPreview中直接通过MainActivity()手动创建了Activity实例。Android的Activity必须由系统框架调度初始化,手动创建的实例没有触发生命周期回调、没有绑定有效上下文、也没有加载布局,调用findViewById时自然无法找到对应控件,触发空指针异常。
正确实现方案
Bitmap实现了Parcelable接口,可以直接通过Intent在Activity之间传递,不需要跨Activity调用方法,修改代码如下:
1. 修改MainActivity的takePhoto方法
跳转前先获取预览Bitmap,处理后塞入Intent:
private fun takePhoto() { Toast.makeText(baseContext, "Processing ..", Toast.LENGTH_SHORT).show() // 先校验预览Bitmap是否可获取 val sourceBitmap = viewFinder.bitmap ?: run { Toast.makeText(this, "预览未就绪,请稍后重试", Toast.LENGTH_SHORT).show() return@takePhoto } // 缩放至目标尺寸 val scaledBitmap = Bitmap.createScaledBitmap(sourceBitmap, 200, 200, true) // 封装到Intent中 val intent = Intent(this, VirtualPreview::class.java) intent.putExtra("preview_bitmap", scaledBitmap) startActivity(intent) }
你原来单独封装的getBitmap方法可以直接删除,不需要保留。
2. 修改VirtualPreview的onCreate方法
从Intent中取出Bitmap直接设置给ImageView:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_virtual_preview) // 初始化控件 imageView = findViewById(R.id.imagePreview) acceptButton = findViewById(R.id.acceptButton) denyButton = findViewById(R.id.denyButton) // 从Intent取Bitmap val bitmapPreview = intent.getParcelableExtra<Bitmap>("preview_bitmap") bitmapPreview?.let { imageView.setImageBitmap(it) } ?: run { Toast.makeText(this, "获取预览图失败", Toast.LENGTH_SHORT).show() finish() } denyButton.setOnClickListener { finish() } }
补充注意事项
- 如果后续需要传递更大的Bitmap(超过1M),不要直接通过Intent传递,避免触发Binder缓冲区超限,可改用全局内存缓存、本地临时文件等方式传递,你当前缩到200*200的尺寸完全可以正常走Intent传递
- 调用
viewFinder.bitmap前请确保CameraX预览已经正常启动,可加状态判断避免拿到空Bitmap
内容的提问来源于stack exchange,提问作者Georgi Tasev
相关产品推荐
相关产品推荐

