美文网首页安卓
有效解决WebView多进程崩溃(续)

有效解决WebView多进程崩溃(续)

作者: 于卫国 | 来源:发表于2021-04-14 14:28 被阅读0次

    在上一篇文章中介绍了可以有效解决WebView多进程崩溃的办法,但隔了两个版本后这个问题竟然死灰复燃,这究竟是怎么回事呢?

    《凉州词》
    葡萄美酒夜光杯,欲饮琵琶马上催。
    醉卧沙场君莫笑,古来征战几人回?
    -王翰

    问题原因

    使用上一篇文章中提供的解决方案上线后取得了不错的效果,但最近这个问题又出现了,使用debug包查看webview数据目录发现系统默认添加了进程名后缀,这是由于用户更新了手机系统导致,使用华为mate20X测试调用WebView.setDataDirectorySuffix自定义后缀已不生效,会默认强制指定后缀为进程名,另外还发现部分华为手机直接将webview目录名app_webview改为了app_hws_webview。

    oppo手机OPPO PDNM00


    华为mate30pro


    荣耀10手机荣耀 HRY AL00A


    解决方案

    综上所述,我们需要针对不同手机系统遍历可能的文件路径,最新解决代码如下:

    private static void handleWebviewDir(Context context) {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
                return;
            }
            try {
                Set<String> pathSet = new HashSet<>();
                String suffix = "";
                String dataPath = context.getDataDir().getAbsolutePath();
                String webViewDir = "/app_webview";
                String huaweiWebViewDir = "/app_hws_webview";
                String lockFile = "/webview_data.lock";
                String processName = getProcessName(context);
                if (!TextUtils.equals(context.getPackageName(), processName)) {//判断不等于默认进程名称
                    suffix = TextUtils.isEmpty(processName) ? context.getPackageName() : processName;
                    WebView.setDataDirectorySuffix(suffix);
                    suffix = "_" + suffix;
                    pathSet.add(dataPath + webViewDir + suffix + lockFile);
                    if (RomUtils.INSTANCE.checkIsHuaweiRom()) {
                        pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
                    }
                }else{
                    //主进程
                    suffix = "_" + processName;
                    pathSet.add(dataPath + webViewDir + lockFile);//默认未添加进程名后缀
                    pathSet.add(dataPath + webViewDir + suffix + lockFile);//系统自动添加了进程名后缀
                    if (RomUtils.INSTANCE.checkIsHuaweiRom()) {//部分华为手机更改了webview目录名
                        pathSet.add(dataPath + huaweiWebViewDir + lockFile);
                        pathSet.add(dataPath + huaweiWebViewDir + suffix + lockFile);
                    }
                }
                for (String path : pathSet) {
                    File file = new File(path);
                    if (file.exists()) {
                        tryLockOrRecreateFile(file);
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @TargetApi(Build.VERSION_CODES.P)
        private static void tryLockOrRecreateFile(File file) {
            try {
                FileLock tryLock = new RandomAccessFile(file, "rw").getChannel().tryLock();
                if (tryLock != null) {
                    tryLock.close();
                } else {
                    createFile(file, file.delete());
                }
            } catch (Exception e) {
                e.printStackTrace();
                boolean deleted = false;
                if (file.exists()) {
                    deleted = file.delete();
                }
                createFile(file, deleted);
            }
        }
    
        private static void createFile(File file, boolean deleted){
            try {
                if (deleted && !file.exists()) {
                    file.createNewFile();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    相关文章

      网友评论

        本文标题:有效解决WebView多进程崩溃(续)

        本文链接:https://www.haomeiwen.com/subject/dqiwcltx.html