Android WebView 升级

举报
帅次 发表于 2024/11/20 14:20:45 2024/11/20
【摘要】 这份文件是Android WebView升级指南,主要介绍了Android WebView升级的项目背景、需求、设备要求及解决方案,详细阐述了WebViewUpgrade的接入流程,包括支持版本、项目导入方法、implementation步骤、使用说明及WebView的相关内容。通过这份指南,开发者可以了解WebView升级的必要性和具体实现方法,确保应用能够兼容最新版本的Android系统,提升

一、项目背景

1.1 需求

        项目需要使用WebView加载合作方公司的Url(里面功能比较多):

  1. 使用了ES6(ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了(所以也被叫作ES2015))

  2. JavaScript 使用的函数,要求 chrome 最低版本是85。

        一系列原因导致WebView加载该链接报错,合作方那边因为某些原因,不想改变现有的代码实现等。需要我们自行解决,那就开整呗。

1.2 设备

  • Android 8.1, WebView 版本 60.xxxx.xxxx.xx(好吧,忘记版本了,页面打不开))

  • Android 8.1, WebView 版本 61.0.3163.98(页面打不开)

  • Android 11,  WebView 版本 83.0.4103.120(视频无法播放,厂商给的答复是不支持,具体原因没说)

查看版本号:

  1. 可以进入设置-开发者模式-Webview实现可以看到 Webview 内核版本号。

  2. adb 命令: adb shell pm dump com.android.webview|grep version

adb shell pm dump com.android.webview|grep version
    versionCode=410412053 minSdk=21 targetSdk=30
    versionName=83.0.4103.120
    signatures=PackageSignatures{48d4530 version:3, signatures:[63b96fc5], past signatures:[]}

1.3 解决方案

1.腾讯X5内核,还是加载失败,以为是集成错误。特意使用微信打开该链接,也是加载失败。

2.更新安装包,因为内嵌WebView的是com.android.webview。

  • 2.1 下载了包名为 95.0.4638.50-463805003_minAPI21版本的包,进行覆盖安装->报错,提示签名文件不一致。

  • 2.2 下载com.android.google.weview_95.0.4638.74_APKPure,安装成功了,加载还是报错。而且在WebView实现->不可选择com.android.google.webview。

3.修改framework-res.apk中配置,允许WebView实现选择com.android.google.webview。这种操作不太合适2C,需要root权限,修改系统文件,一不留神就可能产生其他问题。

4.使用 WebViewUpgrade,这个还是比较强大的,对WebView内核进行升级。已解决低版本无法加载url、视频无法播放的问题。

二、WebViewUpgrade 接入

        WebViewUpgrade的创建者遇到的问题:华为机上因为WebView内核的Chromium版本低于107无法播放H265视频的情况,为了解决上述问题可以用JS实现H265播放,但是会比较卡,就想不能让WebView用应用内的APK作为内核。

2.1 支持版本

  • 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

        当然,你也可以找到其他版本下载安装即可。例如 com.android.webview,我觉得113版本太高,那么你可以下载一个95版本的。或者你不想使用com.android.webview 改用com.google.android.webview也是可以的。

2.2 接入

2.2.1 导入项目(我使用的是这个)

        将Demo的core和download-source模块直接导入到自己项目,修改core中 implementation 'androidx.appcompat:appcompat:1.6.1'的版本。

2.2.2 implementation

implementation 'io.github.jonanorman.android.webviewup:core:0.1.0'// 不需要下载APK时使用
implementation 'io.github.jonanorman.android.webviewup:download-source:0.1.0'// 需要下载APK使用

        如果是低版本,可能会报错。core中 implementation 'androidx.appcompat:appcompat:1.6.1'的版本比较高,需要兼容的SDK版本也比较高。

解决方案:

  • 1.提高项目 SDK 版本。

  • 2.使用exclude。

以上两种方式都可以。

2.3 使用

      设置

    private void setWebView(){
        UpgradeInfo upgradeInfo = new UpgradeInfo(
                "com.android.webview",
                "113.0.5672.136",
                "https://mirror.ghproxy.com/https://raw.githubusercontent.com/JonaNorman/ShareFile/main/com.android.webview_113.0.5672.13_armeabi-v7a.zip",
                "网络");
        String  systemWebViewPackageName = WebViewUpgrade.getSystemWebViewPackageName();
        if (systemWebViewPackageName != null &&systemWebViewPackageName.equals(upgradeInfo.packageName)
                && VersionUtils.compareVersion( WebViewUpgrade.getSystemWebViewPackageVersion(),upgradeInfo.versionName) >= 0) {
            //Toast.makeText(getApplicationContext(), "system webView is larger than the one to be upgraded, so there is no need to upgrade", Toast.LENGTH_LONG).show();
            return;
        }
        UpgradeSource upgradeSource = upgradeInfo.toUpgradeSource(RobotApplication.getInstance());
        if (upgradeSource == null) {
            return;
        }
        WebViewUpgrade.upgrade(upgradeSource);
        updateUpgradeWebViewStatus();
    }
}

这里我使用的是网络下载:

  • 包名:com.android.webview;

  • 版本号:113.0.5672.136

  • 下载内核地址:https://mirror.ghproxy.com/https://raw.githubusercontent.com/JonaNorman/ShareFile/main/com.android.webview_113.0.5672.13_armeabi-v7a.zip

    //更新状态
    private void updateUpgradeWebViewStatus() {
        if (WebViewUpgrade.isProcessing()) {
            LogUtils.e("WebVIewUpgrade","Upgrading...");
        } else if (WebViewUpgrade.isFailed()) {
            LogUtils.e("WebVIewUpgrade","Fail...");
        } else if (WebViewUpgrade.isCompleted()) {
            LogUtils.e("WebVIewUpgrade","complete...");
        }
        int process = (int) (WebViewUpgrade.getUpgradeProcess() * 100);
        LogUtils.e("WebVIewUpgrade","Processing:-----"+process + "%");
        Throwable throwable = WebViewUpgrade.getUpgradeError();
        if (throwable != null) {
            LogUtils.e("WebVIewUpgrade","Throwable.message:" + throwable.getMessage() + "\nstackTrace:" + Log.getStackTraceString(throwable));
        }
    }
public class UpgradeInfo {
    public String title;
    public String url;
    public String packageName;

    public String versionName;
    public String extraInfo;
    public UpgradeInfo(String packageName, String versionName, String url, String extraInfo) {
        this.title = packageName + "\n" + versionName;
        this.extraInfo = !TextUtils.isEmpty(extraInfo) ? extraInfo : "";
        if (!extraInfo.isEmpty()) {
            this.title = this.title + "\n" + extraInfo;
        }
        this.url = url;
        this.packageName = packageName;
        this.versionName = versionName;
    }

    public UpgradeInfo(String packageName, String versionName, String url) {

        this(packageName, versionName, url, "");
    }
    @Nullable
    public UpgradeSource toUpgradeSource(Context context) {
        UpgradeSource upgradeSource = null;
        if (this.extraInfo.equals("网络")) {
            upgradeSource = new UpgradeDownloadSource(
                    context,
                    this.url,
                    new File(context.getFilesDir(), this.packageName + "/" + this.versionName + ".apk")
            );
        } else if (this.extraInfo.equals("内置")) {
            upgradeSource = new UpgradeAssetSource(
                    context,
                    this.url,
                    new File(context.getFilesDir(), this.packageName + "/" + this.versionName + ".apk")
            );
        } else if (this.extraInfo.equals("安装包")) {
            upgradeSource = new UpgradePackageSource(
                    context,
                    this.packageName
            );
        }
        return upgradeSource;
    }
    
public class MainActivity extends BaseActivity implements , UpgradeCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setWebView();
    }
    private void setWebView(){
        ......
    }
    //更新中
    @Override
    public void onUpgradeProcess(float percent) {
        updateUpgradeWebViewStatus();
    }
    //更新完成
    @Override
    public void onUpgradeComplete() {
        updateUpgradeWebViewStatus();
    }
    //更新失败
    @Override
    public void onUpgradeError(Throwable throwable) {
        updateUpgradeWebViewStatus();
    }
}

        注意:这个代码尽量前置,如果无法前置,需要保证,其他地方先不要对WebView进行操作。如果操作了,会导致初始化失败。

        可以先试用Demo尝试功能是否可用,再集成到自己的项目中。

2.4 WebView

        执行完上面的操作后,你就正常操作WebView即可。上面我只是列举了网上下载的例子(第一次下载,只要文件存在,无需重复下载),还支持内置/安装包的形式,我这是应用包体太大,不适合内置。

        这种方式是可行的,但是也有一些小的前置条件需要注意,如果无法前置会导致使用失败。怎么前置才能做到万无一失,就需要根据实际情况来判断了。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。