Jetpack Compose AndroidView新版本在Android 7、10中异常
关于AndroidView的Bug反馈
布局参考:对应布局截图
代码实现
@RequiresApi(Build.VERSION_CODES.M) @Composable fun IjkPlayer(player: IjkMediaPlayer, activityVar: ActivityVar) { AndroidView( factory = { context -> SwithunLog.d("AndroidView # factory") val surfaceView = SurfaceView(context) surfaceView.holder.addCallback(object : SurfaceHolder.Callback { override fun surfaceCreated(holder: SurfaceHolder) { // surfaceView在activity Stop时会destroy,重新切到前台会重新走create,这里要重新setDisplay // 否则会黑屏但是有声音 player.setDisplay(holder) player.start() } override fun surfaceChanged( holder: SurfaceHolder, format: Int, width: Int, height: Int, ) { } override fun surfaceDestroyed(holder: SurfaceHolder) { player.pause() } }) activityVar.mySurfaceView = surfaceView surfaceView }, modifier = Modifier.width(100.dp).height(100.dp), update = { SwithunLog.d("AndroidView # update") }) }
- 该组件在Android 12上运行正常(对应正常显示截图)
- 在Android 7和Android 10上出现异常(对应异常显示截图):仅AndroidView区域全黑,左侧按钮仍可点击但无法显示,布局检查器显示三个系统版本的布局结构一致。
此问题出现在更新Compose相关依赖库后,更新前所有设备均正常工作,更新后的依赖如下:
implementation 'androidx.core:core-ktx:1.9.0' implementation "androidx.compose.ui:ui:1.3.3" implementation 'androidx.compose.material3:material3:1.0.1' implementation "androidx.compose.ui:ui-tooling-preview:1.3.3" implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.0' implementation 'androidx.activity:activity-compose:1.6.1' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "androidx.compose.ui:ui-test-junit4:1.3.3" debugImplementation "androidx.compose.ui:ui-tooling:1.3.3" debugImplementation "androidx.compose.ui:ui-test-manifest:1.3.3"
已尝试使用surfaceView.post { // 设置layoutParam宽高 }方案,但未解决问题,寻求修复方法。
修复建议
调整SurfaceView层级:旧版本Android中Compose的AndroidView可能存在层级覆盖问题,可尝试初始化SurfaceView时添加
surfaceView.setZOrderOnTop(true),或者给AndroidView的Modifier设置z = Float.MAX_VALUE(注意测试对其他视图的影响)。强制触发布局更新:在AndroidView的
update块中主动触发重绘和布局请求:
update = { surfaceView -> SwithunLog.d("AndroidView # update") surfaceView.requestLayout() surfaceView.invalidate() }
- 替换为TextureView:TextureView在Compose中的兼容性更稳定,替换SurfaceView并调整回调逻辑:
val textureView = TextureView(context) textureView.surfaceTextureListener = object : TextureView.SurfaceTextureListener { override fun onSurfaceTextureAvailable(surface: SurfaceTexture, width: Int, height: Int) { player.setSurface(Surface(surface)) player.start() } override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture, width: Int, height: Int) {} override fun onSurfaceTextureDestroyed(surface: SurfaceTexture): Boolean { player.pause() return true } override fun onSurfaceTextureUpdated(surface: SurfaceTexture) {} }
回退依赖版本:暂时回退到更新前正常工作的Compose版本,确认是新版本依赖引入的问题后,再针对性排查具体变更点。
检查硬件加速:在对应Activity的Manifest配置中添加
android:hardwareAccelerated="true",或者初始化SurfaceView时设置surfaceView.setLayerType(View.LAYER_TYPE_HARDWARE, null)。
内容的提问来源于stack exchange,提问作者Swithun
相关产品推荐
相关产品推荐

