问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

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

创作时间:
作者:
@小白创作中心

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

引用
CSDN
1.
https://m.blog.csdn.net/weixin_53290519/article/details/136394547

在Android开发中,WebView的兼容性和性能一直是一个挑战。本文将探讨一种免安装升级系统WebView内核的方法,通过替换系统服务实现WebView内核的动态升级,支持H265视频播放等高级功能。

背景

Android 5.0以后,WebView的升级通常需要通过Google Play安装APK。然而,这种方法并不总是可靠,特别是在华为、Amazon等特殊机型上,系统WebView的Chromium版本往往较低,无法使用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内核的包名变成了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进程
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号