最新的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
这个目录下面有 api、build.gradle 和 src。src/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 发布库的方式建了模块。namespace 是 androidx.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 只会影响 AndroidView 的 update,不会自动理解网页状态。
最容易踩的是重复加载。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 中间这层封装。现在自己写的 WebPage、ComposeWebView、WebViewContainer,都有机会被官方组件收敛一部分重复代码。但具体收敛到什么程度,要等 API 文件出现。
最后
web/web-compose 已经出现在 AndroidX 主干里,模块说明指向"显示网页的 composable",但当前 API 文件还是空的。
相信很多人都会期待Compose版的WebView吧!