Android开发问题收录

2,547 阅读1分钟

Android9及以后多进程使用webview问题

问题描述:

Caused by: java.lang.RuntimeException: Using WebView from more than one process at once
with the same data directory is not supported. https://crbug.com/558377

方法:

送上官网 developer.android.com/reference/a…

帮助没有梯*子的同学

setDataDirectorySuffix
Added in API level 28
public static void setDataDirectorySuffix (String suffix) Define the directory used to store WebView data for the current process. The provided suffix will be used when constructing data and cache directory paths. If this API is not called, no suffix will be used. Each directory can be used by only one process in the application. If more than one process in an app wishes to use WebView, only one process can use the default directory, and other processes must call this API to define a unique suffix.
This means that different processes in the same application cannot directly share WebView-related data, since the data directories must be distinct. Applications that use this API may have to explicitly pass data between processes. For example, login cookies may have to be copied from one process's cookie jar to the other using CookieManager if both processes' WebViews are intended to be logged in.
Most applications should simply ensure that all components of the app that rely on WebView are in the same process, to avoid needing multiple data directories. The disableWebView() method can be used to ensure that the other processes do not use WebView by accident in this case.
This API must be called before any instances of WebView are created in this process and before any other methods in the android.webkit package are called by this process

具体方式如下:

在Application中,加入以下设置

 // 在Application的 onCreate()方法中加入  前面代码不能有初始化Webview
 public void webviewSetPath(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            String processName = ProcessUtils.getCurrentProcessName(context);
            ProcessUtils.isMainProcess(context);
            if (!ProcessUtils.isMainProcess(context)) {  //判断不等于默认进程名称
                WebView.setDataDirectorySuffix(processName);
            }
        }
    }
    
 public static String getCurrentProcessName(Context context) {
        if (context.getApplicationContext() != null) {
            context = context.getApplicationContext();
        }
        int pid = android.os.Process.myPid();
        String processName = "";
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (manager != null && manager.getRunningAppProcesses() != null && !manager.getRunningAppProcesses().isEmpty()) {
            for (ActivityManager.RunningAppProcessInfo process : manager.getRunningAppProcesses()) {
                if (process.pid == pid) {
                    processName = process.processName;
                }
            }
        }
        return processName;
    }
    public static boolean isMainProcess(Context context) {
        boolean ret = true;
        String processName = getCurrentProcessName(context);
        if (processName != null) {
            ret = processName.equals(context.getPackageName());
        }
        return ret;
    }