AndroidX 官宣信号:Compose版WebView要来了!

最新的AndroidX 主干里已经出现了 web/web-compose 模块。目录在 platform/frameworks/support/web/web-compose,包文档写的是 web.compose,用途是提供显示网页的 composable。现在 api/current.txt 还没有任何公开类,所以它更像一个刚露面的 Jetpack Web Compose 信号。

源码信号

这次被看到的是 AndroidX 仓库里的新目录:

bash 复制代码
platform/frameworks/support/+/refs/heads/androidx-main/web/web-compose/src/main/kotlin/androidx/web

这个目录下面有 apibuild.gradlesrcsrc/main/kotlin/androidx/web 里现在只有一个文档文件,内容很短:模块名是 Web Web Compose,包名是 web.compose,说明是提供一个展示网页的 composable。

build.gradle 里能确认三件事:

bash 复制代码
android {
    namespace = "androidx.web.compose"
}

androidx {
    name = "web:web-compose"
    type = SoftwareType.PUBLISHED_LIBRARY
    inceptionYear = "2026"
}

这里的 PUBLISHED_LIBRARY 说明它按 AndroidX 发布库的方式建了模块。namespaceandroidx.web.compose,模块名是 web:web-compose。但这还不能等同于 Maven 已经有可用版本,也不能推导出最终依赖坐标和类名。

更关键的是 api/current.txt。现在这个文件只有签名格式,没有任何公开 API:

bash 复制代码
// Signature format: 4.0

所以现阶段不要写"某个 Web composable 已经能用了"。能确定的只有模块已经进了 AndroidX 主干,公开接口还没露出来。

现在的写法

在 Jetpack Compose 里展示网页,现在最常见的方式还是 AndroidView + WebView。Compose 负责布局和状态,真正渲染网页的还是平台 WebView

一个最小封装大概是这样:

bash 复制代码
@Composable
fun WebPage(
    url: String,
    modifier: Modifier = Modifier,
) {
    var webView: WebView? by remember { mutableStateOf<WebView?>(null) }

    AndroidView(
        modifier = modifier.fillMaxSize(),
        factory = { context ->
            WebView(context).apply {
                webViewClient = WebViewClient()
                settings.javaScriptEnabled = false
                loadUrl(url)
                webView = this
            }
        },
        update = { view ->
            if (view.url != url) {
                view.loadUrl(url)
            }
        }
    )

    DisposableEffect(Unit) {
        onDispose {
            webView?.destroy()
            webView = null
        }
    }
}

这段代码能跑,但它只是把 View 塞进 Compose。页面加载状态、错误页、返回栈、文件选择、权限请求、Cookie、深色模式、滚动冲突、生命周期释放,都要自己处理。写一个简单内嵌网页没问题,写成业务组件就会开始长代码。

WebView 的边界

WebView 不是普通的 Compose 节点。它有自己的进程、渲染、缓存、历史栈和生命周期。Compose 的 recomposition 只会影响 AndroidViewupdate,不会自动理解网页状态。

最容易踩的是重复加载。update 每次重组都有机会执行,如果里面直接 loadUrl(url),列表滚动、状态变化、父节点重组都可能让网页重新加载。上面的代码用了 if (view.url != url),目的就是避免无意义刷新。

第二个问题是释放。WebView 持有的资源比普通 View 重,页面里还有 JS、图片、视频和缓存。Composable 离开页面时,如果没有把 WebView 销毁,内存和后台行为就可能变得很难排查。

还有返回处理。Compose 页面通常用 BackHandler 接系统返回,但 WebView 自己有历史栈。实际业务里经常要先判断 canGoBack(),网页能返回时走 goBack(),网页没有历史时再退出当前 Compose 页面。

bash 复制代码
BackHandler(enabled = webView?.canGoBack() == true) {
    webView?.goBack()
}

这些代码本身不复杂,麻烦的是每个项目都会再加一层业务规则。比如哪些域名允许打开、加载失败显示什么、登录 Cookie 怎么同步、网页标题怎么回传给顶部栏。最后封装出来的组件往往已经不是一个简单 AndroidView

名字容易误读

Jetpack Web Compose 这个名字容易和 Compose for Web 混在一起。后者是 Kotlin/Wasm、Kotlin/JS 那条线,目标是浏览器里的 UI。AndroidX 这个 web-compose 目录出现在 platform/frameworks/support,说明文字也指向"显示网页的 composable"。

从现有源码看,它更像 Android App 里用 Compose 展示网页内容的组件,而不是把 Compose UI 编译到 Web 平台。这个边界要分清楚,不然很容易把两个技术方向讲混。

对 Android 开发者来说,它可能补的是 AndroidView + WebView 中间这层封装。现在自己写的 WebPageComposeWebViewWebViewContainer,都有机会被官方组件收敛一部分重复代码。但具体收敛到什么程度,要等 API 文件出现。

最后

web/web-compose 已经出现在 AndroidX 主干里,模块说明指向"显示网页的 composable",但当前 API 文件还是空的。

相信很多人都会期待Compose版的WebView吧!

#Android #JetpackCompose #AndroidX #WebView

相关推荐
如此风景19 小时前
Kotlin Flow操作符学习
android·kotlin
plainGeekDev19 小时前
GreenDAO → Room
android·java·kotlin
plainGeekDev1 天前
ButterKnife → ViewBinding
android·java·kotlin
Kapaseker2 天前
一文吃透 Kotlin 集合操作符
android·kotlin
plainGeekDev3 天前
Activity 间传值 → Navigation 参数
android·java·kotlin
plainGeekDev3 天前
onActivityResult → ActivityResult API
android·java·kotlin
alexhilton4 天前
Android车载OS中的Remote Compose
android·kotlin·android jetpack
plainGeekDev4 天前
广播接收器 → Flow + Lifecycle
android·java·kotlin
plainGeekDev4 天前
EventBus → SharedFlow
android·java·kotlin