Compose AndroidView在旧设备返回后不渲染问题求助(Android 6/Samsung S5)
问题现象
在Compose中使用AndroidView嵌套SurfaceView实现相机预览功能,多数设备表现正常,但在**三星S5(Android 21 API)**上出现异常:按下Home键返回桌面后,重新从启动器进入应用(触发onStart、onResume生命周期回调),相机预览停止更新,显示黑屏或最后一帧画面。同API版本的Pixel模拟器无此问题,三星S22(Android14)、三星S10(Android12)等新设备也无法复现该问题。
无临时修复时,仅在应用首次启动(触发ActivityonCreate)或切换页面(AndroidView离开并重新进入组合)时,相机预览才能正常工作。
初始实现代码
Scaffold { innerPadding -> // camera preview: AndroidView( modifier = Modifier.fillMaxSize(), factory = { SurfaceView(it) }, ) Column( modifier = Modifier .fillMaxSize() .padding(innerPadding) ) { /// UI / controls } }
修复方案代码
通过在Composable的onStart生命周期事件中调用SurfaceView.invalidate(),问题得到解决,返回应用后相机预览可正常更新:
var surfaceView by remember { mutableStateOf<SurfaceView?>(null) } LifecycleEventEffect(event = Lifecycle.Event.ON_START) { surfaceView?.invalidate() } Scaffold { innerPadding -> // camera preview: AndroidView( modifier = Modifier.fillMaxSize(), factory = { SurfaceView(it).also { surfaceView = it } }, ) Column( modifier = Modifier .fillMaxSize() .padding(innerPadding) ) { /// UI / controls } }
问题原因解析
三星旧设备的SurfaceView定制逻辑差异
Android 5.0(API21)的三星定制系统,在应用从后台恢复到前台时,对SurfaceView的缓冲区管理或预览回调的恢复逻辑存在瑕疵。原生系统(如Pixel模拟器)会主动触发SurfaceView的重绘流程,重新绑定相机预览数据,但三星S5的定制系统未正确执行这一步,导致画面冻结。Compose与旧View系统的交互适配细节
Compose的AndroidView组件在旧API设备上,对嵌套View的生命周期同步可能存在遗漏。当应用恢复时,AndroidView没有主动触发SurfaceView的重绘请求,而调用invalidate()会强制SurfaceView触发绘制流程,重新建立与相机预览数据流的连接,从而恢复画面更新。不属于Compose核心Bug
该问题并非Compose的通用Bug,而是特定厂商旧系统与Compose View交互的边缘兼容场景。新设备和原生模拟器无此问题,说明后续Android系统版本迭代以及Compose的更新,已经完善了这类场景的适配逻辑。
内容的提问来源于stack exchange,提问作者user924

