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

如何解决Android Jetpack Compose返回时的SIGSEGV崩溃问题

问题:Jetpack Compose返回导航时触发RenderThread原生崩溃

在Android Jetpack Compose开发场景下,从MailRoomScreen页面执行返回导航时,触发以下原生崩溃:

Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x20 in tid 19443 (RenderThread)

测试验证:将Tab页面替换为简单Text组件后,崩溃问题消失,确认问题与WebView在Compose中的生命周期管理相关。


问题根源分析

从提供的代码来看,核心问题集中在WebView的实例管理与销毁时机上:

  1. WebView实例重复创建与冲突销毁:

    • MailRoomScreen中通过remember创建WebView实例并传递给MailRoomInScreen
    • 但MailRoomInScreen内部又重新通过remember创建了全新的WebView实例,同时在DisposableEffect中执行销毁逻辑
    • 返回时,MailRoomScreen的返回按钮再次调用外部WebView的destroy(),导致同一生命周期内多次销毁或销毁已释放的WebView资源,触发RenderThread内存访问错误
  2. 销毁时机不当:

    • 在返回按钮点击时直接调用webView.destroy(),此时Composable尚未完成生命周期清理,WebView可能仍处于RenderThread的渲染队列中,强制销毁导致原生层访问已释放的内存

修复方案

1. 统一WebView实例管理,避免跨Composable传递

移除MailRoomScreen中创建的WebView实例,将WebView的创建与生命周期完全交给MailRoomInScreen管理:

  • 修改MailRoomScreen中调用MailRoomInScreen的代码:
// MailRoomScreen内HorizontalPager的Tab 0逻辑
0 -> {
    MailRoomInScreen(
        mailRoomViewModel = mailroomViewModel,
        navController = navController
    )
}
  • 修改MailRoomInScreen的参数定义,移除多余的WebView参数:
@Composable
fun MailRoomInScreen(
    mailRoomViewModel: MailroomViewModel,
    navController: NavHostController
) {
    // 内部保持原有的WebView remember与DisposableEffect逻辑
}

2. 移除返回按钮中的主动销毁调用

删除MailRoomScreen返回按钮内的webView.destroy(),完全依赖MailRoomInScreen的DisposableEffect处理销毁——该Effect会在Composable从Composition中移除时自动执行,符合WebView的生命周期规律:

IconButton(
    onClick = {
        navController.popBackStack() // 仅保留导航逻辑
    }
) {
    Icon(
        Icons.Filled.ArrowBack,
        contentDescription = "Back"
    )
}

3. 优化WebView销毁的安全流程

在MailRoomInScreen的DisposableEffect中,增加更安全的销毁步骤,确保WebView完全停止渲染后再释放资源:

DisposableEffect(Unit) {
    onDispose {
        webView.stopLoading()
        webView.loadUrl("about:blank") // 清空页面内容
        webView.removeJavascriptInterface("Android") // 移除JS接口避免内存泄漏
        webView.destroy()
    }
}

4. 调整HorizontalPager的页面缓存策略

HorizontalPager默认保留相邻页面实例(offscreenLimit=1),切换到Tab 1时,Tab 0的MailRoomInScreen仍处于Composition中,不会触发销毁。若需要切换Tab时立即销毁WebView,可设置offscreenLimit=0:

HorizontalPager(
    state = pagerState,
    modifier = Modifier.fillMaxSize(),
    offscreenLimit = 0
) {
    // 页面内容逻辑
}

内容的提问来源于stack exchange,提问作者M B

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:09:53