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进程

相关推荐
excel5 分钟前
前端必备:从能力检测到 UA-CH,浏览器客户端检测的完整指南
前端
前端小巷子12 分钟前
Vue 3全面提速剖析
前端·vue.js·面试
悟空聊架构18 分钟前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构
CodeSheep20 分钟前
国内 IT 公司时薪排行榜。
前端·后端·程序员
尖椒土豆sss24 分钟前
踩坑vue项目中使用 iframe 嵌套子系统无法登录,不报错问题!
前端·vue.js
遗悲风25 分钟前
html二次作业
前端·html
江城开朗的豌豆28 分钟前
React输入框优化:如何精准获取用户输入完成后的最终值?
前端·javascript·全栈
CF14年老兵28 分钟前
从卡顿到飞驰:我是如何用WebAssembly引爆React性能的
前端·react.js·trae
画月的亮31 分钟前
前端处理导出PDF。Vue导出pdf
前端·vue.js·pdf
江城开朗的豌豆37 分钟前
拆解Redux:从零手写一个状态管理器,彻底搞懂它的魔法!
前端·javascript·react.js