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

相关推荐
btown3 天前
Kotlin 版 MyBatis-Plus 查询优雅解决方案
kotlin
小二·3 天前
车载数字座舱实战:用魔珐星云打造下一代智能驾乘助手(附 Android/Kotlin 完整代码)
开发语言·kotlin
我命由我123453 天前
Android 开发问题:java.lang.NoSuchMethodError:No virtual method readAllBytes()
android·java·java-ee·kotlin·android studio·android-studio·android runtime
Kapaseker3 天前
你是不是还没用过 select?实战 Kotlin select
android·kotlin
plainGeekDev4 天前
synchronized → Coroutines
android·java·kotlin
唐青枫4 天前
Java Gradle 实战指南:从 Wrapper、Kotlin DSL 到 Spring Boot 多模块构建
java·kotlin·gradle
帅次5 天前
Kotlin Flow 与 StateFlow:UI 单向数据流基础
开发语言·ui·kotlin·stateflow·onlifecycle
Kapaseker5 天前
Sequence 一定比 List 快?等等,我们先从基础讲起
android·kotlin
zhangjin11206 天前
Android Studio创建HelloWorld(kotlin版本)
android·kotlin·android studio
怣疯knight6 天前
kotlin安卓应用打包编译卡死的可能原因
android·kotlin