在安卓系统中设置 webview 为最新的实现
我们开发的一些安卓设备比较老旧,还停留在 android 11 的版本,这个版本自带的 webview 版本是 83 的,这就导致了开发过程中的很多 h5 属性不兼容,但是我们开发用的电脑的浏览器一般都是最新版本,这个时候要去做适配,是很麻烦的。
如下图

可能一眼看不出来问题,跟下面的对比就知道了

这个的主要原因呢,我们可以在设置里面看到

这里只有一个 webview 的实现,而我们开发调试的浏览器版本是 150 的,如果不想做太多前端页面修改的话,这里建议升级 webview 的版本,当然下载的时候也要注意,webview 的版本其实有很多,我们当前安卓系统版本是 11,所以 minsdk 版本不能高于 30.
于是我从 apkmirror 里下载了这个版本
https://www.apkmirror.com/apk/google-inc/android-system-webview/android-system-webview-150-0-7871-48-release/android-system-webview-150-0-7871-48-android-apk-download/download/?key=3889c29160e2c5f02475547173f6cabf15f1d66c&forcebaseapk=true
你也可以根据你自己的系统版本下载最新的
但是安装完成后你还是没有看到最新的实现,这里请参考下面的教程来操作
核心原因:
Android 11 不会因为安装了新版 WebView APK 就自动把它显示在“开发者选项 -> WebView 实现”里。系统只会显示 ROM 配置中允许的 WebView provider。这个配置来自 `framework-res.apk` 的 `res/xml/config_webview_packages.xml`。如果里面只有 `com.android.webview`,那么即使已经安装 `com.google.android.webview 150`,开发者选项也只会显示 83。
解决方案:
添加一个系统 overlay APK,覆盖 `android:xml/config_webview_packages`,把 `com.google.android.webview` 加入 provider 列表,然后重启并切换 provider
由于我们的安卓是接在一个 linux 主机上的,所以下面的过程我都是通过 ssh 来连接这个 linux 主机来操作的,当然如果你是直接连接的,会比我这里简单一些
## 1. 准备变量
在你的控制电脑上设置变量。控制电脑可以是 Mac,也可以是另一台有 `ssh`、`scp`、`curl`、`java/keytool/jarsigner` 的 Linux。
```bash
export LINUX_HOST="10.4.80.129"
export LINUX_PORT="222"
export LINUX_USER="edge"
export ANDROID_IP="192.168.2.210"
export ADB="/home/edge/AndroidToolBox/adb"
```
如果 SSH 密码是示例里的 `security@xxxx`,可以手动输入密码。也可以安装 `sshpass` 后使用:
```bash
export SSHPASS='security@edge'
```
## 2. 连接 Linux 跳板机并确认 adb
登录 Linux:
```bash
ssh -p "$LINUX_PORT" "$LINUX_USER@$LINUX_HOST"
```
在 Linux 上确认 adb 路径:
```bash
command -v adb || find /usr /opt /home/edge -type f -name adb 2>/dev/null | head -20
```
示例中 adb 位于:
```bash
/home/edge/AndroidToolBox/adb
```
连接 Android 设备:
```bash
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb devices -l
```
期望看到类似:
```text
192.168.2.210:5555 device product:rk3568_QY model:rk3568_QY device:rk3568_QY
```
## 3. 检查当前 WebView 状态
在 Linux 上执行:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell getprop ro.build.version.release
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell getprop ro.build.version.sdk
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys webviewupdate
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell 'pm list packages -f | grep -Ei "webview|chrome|trichrome|google"'
```
如果问题存在,`dumpsys webviewupdate` 里通常只会有:
```text
Current WebView package (name, version): (com.android.webview, 83.0.4103.120)
WebView packages:
Valid package com.android.webview ...
```
即使 `pm list packages` 能看到:
```text
com.google.android.webview
```
开发者选项仍然不会显示它,因为它还不在系统 provider 白名单中。
也可以尝试直接切换,通常会失败:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell cmd webviewupdate set-webview-implementation com.google.android.webview
```
失败输出类似:
```text
Failed to switch to com.google.android.webview, the WebView implementation is now provided by com.android.webview.
```
## 4. 确认设备允许 root/remount
这个方案需要写入 `/product/overlay`,所以需要 root adb 和 remount。
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 root
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell id
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 remount
```
期望 `id` 输出中包含:
```text
uid=0(root)
```
期望 `remount` 输出:
```text
remount succeeded
```
如果 `adb root` 或 `adb remount` 失败,这个教程不能直接执行。你需要先让设备支持 root adb/remount,或者改 ROM 源码后重新打包系统镜像。
## 5. 拉取设备上的 framework-res.apk
回到你的控制电脑执行:
```bash
mkdir -p work/webview_overlay
ssh -p "$LINUX_PORT" "$LINUX_USER@$LINUX_HOST" \
"$ADB -s $ANDROID_IP:5555 exec-out cat /system/framework/framework-res.apk" \
> work/webview_overlay/framework-res.apk
```
检查文件:
```bash
ls -lh work/webview_overlay/framework-res.apk
```
## 6. 下载 aapt2
在控制电脑执行:
```bash
cd work/webview_overlay
export AAPT2_VERSION="9.3.0-15703166"
curl -L --fail -o aapt2.jar \
"https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/${AAPT2_VERSION}/aapt2-${AAPT2_VERSION}-osx.jar"
jar xf aapt2.jar aapt2
chmod +x aapt2
```
如果你的控制电脑是 Linux,把下载 URL 里的 `osx.jar` 改成 `linux.jar`:
```bash
curl -L --fail -o aapt2.jar \
"https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/${AAPT2_VERSION}/aapt2-${AAPT2_VERSION}-linux.jar"
```
## 7. 查看原始 WebView provider 配置
```bash
./aapt2 dump xmltree --file res/xml/config_webview_packages.xml framework-res.apk
```
如果原始 ROM 只有旧版 WebView,你会看到类似:
```text
webviewprovider
availableByDefault=true
description="Android WebView"
packageName="com.android.webview"
```
## 8. 创建 overlay 工程
在 `work/webview_overlay` 目录下创建文件:
```bash
mkdir -p src/res/xml build
```
创建 `src/AndroidManifest.xml`:
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codex.overlay.webviewprovider"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="30" android:targetSdkVersion="30" />
<overlay
android:targetPackage="android"
android:isStatic="true"
android:priority="999" />
</manifest>
```
创建 `src/res/xml/config_webview_packages.xml`:
```xml
<?xml version="1.0" encoding="utf-8"?>
<webviewproviders>
<webviewprovider
description="Android WebView"
packageName="com.android.webview"
availableByDefault="true" />
<webviewprovider
description="Google WebView"
packageName="com.google.android.webview"
availableByDefault="true" />
</webviewproviders>
```
说明:
- 保留原来的 `com.android.webview`,避免系统失去 fallback。
- 新增 `com.google.android.webview`,让已安装的 Google WebView 能进入开发者选项和 WebViewUpdateService。
- 如果你的目标包名不是 `com.google.android.webview`,把 XML 里的包名替换成实际包名。
## 9. 编译 overlay APK
```bash
./aapt2 compile --dir src/res -o build/compiled.zip
./aapt2 link \
-I framework-res.apk \
--manifest src/AndroidManifest.xml \
-o build/WebViewProviderOverlay-unsigned.apk \
build/compiled.zip
```
## 10. 签名 overlay APK
控制电脑需要有 JDK 的 `keytool` 和 `jarsigner`。
```bash
keytool -genkeypair \
-keystore build/debug.keystore \
-storepass android \
-keypass android \
-alias androiddebugkey \
-keyalg RSA \
-keysize 2048 \
-validity 10000 \
-dname 'CN=Android Debug,O=Manual,C=US'
jarsigner \
-keystore build/debug.keystore \
-storepass android \
-keypass android \
-signedjar build/WebViewProviderOverlay.apk \
build/WebViewProviderOverlay-unsigned.apk \
androiddebugkey
jarsigner -verify build/WebViewProviderOverlay.apk
ls -lh build/WebViewProviderOverlay.apk
```
自签名证书会有 warning,这是正常的。只要 `jar verified` 即可。
## 11. 传 overlay APK 到 Linux
回到控制电脑的 `work/webview_overlay` 目录,执行:
```bash
scp -P "$LINUX_PORT" build/WebViewProviderOverlay.apk \
"$LINUX_USER@$LINUX_HOST:/tmp/WebViewProviderOverlay.apk"
```
如果使用 `sshpass`:
```bash
sshpass -e scp -P "$LINUX_PORT" build/WebViewProviderOverlay.apk \
"$LINUX_USER@$LINUX_HOST:/tmp/WebViewProviderOverlay.apk"
```
## 12. 推送 overlay 到 Android 系统分区
登录 Linux:
```bash
ssh -p "$LINUX_PORT" "$LINUX_USER@$LINUX_HOST"
```
执行:
```bash
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 root
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 remount
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
'mkdir -p /product/overlay/WebViewProviderOverlay && chmod 755 /product/overlay/WebViewProviderOverlay'
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 push \
/tmp/WebViewProviderOverlay.apk \
/product/overlay/WebViewProviderOverlay/WebViewProviderOverlay.apk
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
'chmod 644 /product/overlay/WebViewProviderOverlay/WebViewProviderOverlay.apk && chown root:root /product/overlay/WebViewProviderOverlay/WebViewProviderOverlay.apk && restorecon -R /product/overlay/WebViewProviderOverlay 2>/dev/null || true && ls -lZ /product/overlay/WebViewProviderOverlay'
```
期望看到:
```text
-rw-r--r-- 1 root root ... WebViewProviderOverlay.apk
```
## 13. 重启 Android
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 reboot
```
等待设备重新上线:
```bash
for i in $(seq 1 60); do
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555 >/dev/null 2>&1
state=$(/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 get-state 2>/dev/null)
if [ "$state" = device ]; then
echo online
break
fi
sleep 2
done
```
## 14. 验证 overlay 是否生效
重新连接并 root:
```bash
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 root
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
```
查看 overlay lookup:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
cmd overlay lookup --verbose android android:xml/config_webview_packages
```
如果成功,会看到类似:
```text
Found initial: com.codex.overlay.webviewprovider
Overlaid: com.codex.overlay.webviewprovider
res/xml/config_webview_packages.xml
```
查看 WebViewUpdateService:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys webviewupdate
```
成功后应该看到两个 valid provider:
```text
Valid package com.android.webview ...
Valid package com.google.android.webview ...
```
并且可能已经自动切到新版:
```text
Current WebView package (name, version): (com.google.android.webview, 150.0.7871.48)
```
## 15. 手动切换到新版 WebView
如果还没有自动切换,执行:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
cmd webviewupdate set-webview-implementation com.google.android.webview
```
期望输出:
```text
Success
```
最终确认:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys webviewupdate
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell settings get global webview_provider
```
期望结果:
```text
Current WebView package (name, version): (com.google.android.webview, 150.0.7871.48)
Preferred WebView package (name, version): (com.google.android.webview, 150.0.7871.48)
```
以及:
```text
com.google.android.webview
```
此时开发者选项里的 WebView 实现应该能看到并选中 Google WebView 150。
## 16. 常见问题
### adb: command not found
Linux 上没有把 adb 加入 PATH。先找 adb:
```bash
find /usr /opt /home/edge -type f -name adb 2>/dev/null | head -20
```
然后用完整路径执行,例如:
```bash
/home/edge/AndroidToolBox/adb devices -l
```
### set-webview-implementation 失败
如果输出:
```text
Failed to switch to com.google.android.webview
```
先检查:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys webviewupdate
```
如果 `WebView packages` 里没有 `com.google.android.webview`,说明 overlay 没生效,回到第 14 步查 `cmd overlay lookup`。
### dumpsys webviewupdate 里显示 Invalid package
常见原因:
- 目标 WebView 没有安装到 user 0。
- 目标 WebView 被禁用。
- `targetSdkVersion` 低于系统要求。
- versionCode 低于系统要求。
- ROM 是非 debuggable/user build,签名校验更严格。
检查目标包:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys package com.google.android.webview | grep -E 'versionName|versionCode|targetSdk|enabled=|installed='
```
启用目标包:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell pm enable com.google.android.webview
```
### overlay 文件存在但没生效
检查 overlay lookup:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell cmd overlay lookup --verbose android android:xml/config_webview_packages
```
检查日志:
```bash
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
'logcat -d -v time | grep -Ei "WebViewProviderOverlay|codex.overlay|PackageManager|OverlayConfig|idmap|overlay" | tail -120'
```
如果 `/product/overlay` 不被该 ROM 扫描,可以尝试把 APK 放到:
```text
/vendor/overlay/WebViewProviderOverlay/WebViewProviderOverlay.apk
/system/product/overlay/WebViewProviderOverlay/WebViewProviderOverlay.apk
```
放置后同样设置权限并重启。
## 17. 回滚方法
如果要恢复原状,删除 overlay APK 并重启:
```bash
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 root
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 remount
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell \
'rm -rf /product/overlay/WebViewProviderOverlay'
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 reboot
```
重启后验证:
```bash
/home/edge/AndroidToolBox/adb connect 192.168.2.210:5555
/home/edge/AndroidToolBox/adb -s 192.168.2.210:5555 shell dumpsys webviewupdate
```
应该只剩 ROM 原始的 `com.android.webview` provider。
## 18. 一句话总结
这类问题的本质不是新版 WebView 没装好,而是 ROM 的 WebView provider 白名单没有包含新版 WebView 的包名。通过系统 overlay 修改 `config_webview_packages.xml` 后,Android 11 的 WebViewUpdateService 才会把 `com.google.android.webview` 当作合法 WebView 实现,并允许切换到 150。


浙公网安备 33010602011771号