Android免安装升级系统WebView内核探索

背景

Android5.0以后WebView升级需要去Google Play安装APK(图一),就算安装了以后也不一定能行,像华为、Amazon等特殊机型WebView的Chromium版本一般比较低,只能用它自己的WebView无法用Google的WebView(图二)。

华为机上WebView内核的Chromium版本低于107无法播放H265视频,为了解决上述问题可以用JS实现H265播放,但是会比较卡,也可以用腾讯的X5内核,但是免费版实际chromium版本是89不支持H265视频,这个时候我就想能不能用App内的WebView APK作为内核,下图是升级WebView内核的前后效果对比

升级前在华为机上的系统WebView内核包名是com.huawei.webview,版本是14.0.0.331,UserAgent中的Chromium实际版本是99.0.4844.88,如下图所示小于107不支持H265播放

把WebView内核的包名、版本、包地址传到以下代码升级内核成功后就可以播放H265视频了

WebView内核选择页面如下图所示

升级成功后WebView内核的包名变成了com.google.android.webview,UserAgent中的Chromium实际版本也变成了122.0.6261.64

项目地址:WebViewUpgrade,这个项目是为了解决WebView碎片化而产生,当前处于测试阶段,如果你觉得有所收获,给这个库点个赞吧,你的鼓励是我前进最大的动力,

兼容性

Android的设备五花八门,已测试以下功能和机型

功能特性

WebView包名 系统版本
com.google.android.webview 122.0.6261.64
com.android.webview 113.0.5672.136
com.huawei.webview 14.0.0.331
com.android.chrome 122.0.6261.43
com.amazon.webview.chromium 118-5993-tv.5993.155.51

机型

厂商 系统版本
华为Mate30 12
小米10 11
VIVO NEX A 10
OPPO FIND X5 14

原理介绍

其实原理很简单,从上图中可以看到WebView初始化的时候会根据WebViewProviderResponse (WebViewUpdateService调用waitForAndGetProvider)和PackageInfo (PacakgeManagerService调用getPackageInfo)生成WebViewFactoryProivder,也就是说只要hook这两个方法就行,替换WebViewUpdateService和PacakgeManagerService的调用很简单,其实就是替换Binder的本地接口调用,网上方案很多就不展开了,如果不清楚的可以直接看代码

替换waitForAndGetProvider值得注意的是WebViewProviderResponse 对象的packageInfo查询时flags要设置成GET_SHARED_LIBRARY_FILES|GET_SIGNATURES|GET_META_DATA ,后续代码中会用这些数据,不然会崩溃。

替换getPackageInfo值得注意的是

  1. getPackageArchiveInfo查询未安装Apk的PackageInfo
  2. 有些APK加上GET_SIGNATURES查询PackageInfo会找不到
  3. getPackageArchiveInfo查询出来的PackageInfo不存在nativeLibraryDir,需要手动赋值
  4. nativeLibraryDir传入的so路径需要运行时处理器指令集的ABI一样,不然会崩溃
  5. 部分手机的packageInfo.applicationInfo.sourceDir不存在,需要手动赋值

有两个功能还没实现,希望有了解的朋友能提交代码解决这两个问题。

  1. 运行时动态切换WebView内核,现在只能在WebView未初始化之前替换,原因是因为会报错UnsatisfiedLinkError: Shared library "/system/lib64/libwebviewchromium_plat_support.so" already opened by ClassLoader,WebView内核中会调用System.loadLibrary加载libwebviewchromium_plat_support.so,而系统限制同一个so只能被一个classLoader加载。

  2. 不支持多进程功能,如果把WebViewUpdateService的isMultiProcessEnabled设为true,会报错java.lang.RuntimeException: Illegal meta data value: the child service doesn't exist, 就算把这个错误解决了,也无法用Process.startWebView手动启动WebViewZygote进程

相关推荐
AINative软件工程6 分钟前
编程
前端·llm
晴天167 分钟前
peerDependencies 全面解析:前端依赖生态的核心机制与实战指南
前端·npm
I'mChloe8 分钟前
群晖部署 image-matting:把人像去背景做成一个随开随用的 Web 工具
android·前端
千里马-horse10 分钟前
第 61 章:设备策略与 Android 企业版
android·aosp
程序员蜡笔熊13 分钟前
Vite 8 换芯实测:Rolldown 替掉双引擎,构建快 3.19 倍
前端·javascript·vue
2501_9151063214 分钟前
Flutter iOS混淆打包详细教程与步骤
android·flutter·ios·小程序·uni-app·iphone·webview
右耳朵猫AI19 分钟前
Web前端周刊2026W36 | pnpm 12 Rust 重写、Remix 3 RC、Node.js 26.8.0、htmx 4.0 大版本
前端·rust·node.js
三少爷的鞋33 分钟前
Android 架构演进:从生命周期事件到结构化任务
android
平头哥~35 分钟前
Day 21 | animation 与 keyframes:把动画从 A 到 B 变成多点编排
前端·css·css3·css学习
一笑的小酒馆8 小时前
AndroidKMP之网络请求
android