Android Pie (9.0) WebView in multi-process

后端 未结 3 1813
既然无缘
既然无缘 2020-12-24 02:31

Starting Android Pie (API 28), Google isn\'t allowing using a single WebView instance in 2 different processes.

Documentation: https://developer.android.com/referenc

相关标签:
3条回答
  • 2020-12-24 02:53

    Solved.

    My project hosts AdMob ads and I call the MobileAds.initialize() method inside my Application class onCreate(). The ads initializer loads a WebView which is now forbidden to do in a new process before you call the WebView.setDataDirectorySuffix("dir_name_no_separator") method.

    When the second process is created, it also goes through the same application create flow, meaning it calls the same onCreate() inside the Application class, which calls the MobileAds.initialize() that tries to create a new WebView instance and by that causes the crash.

    IllegalStateException: Can't set data directory suffix: WebView already initialized
    

    How I solved this?

    I get the process name using the below method and check if it's my main process - call the MobileAds.initialize() method and if it's my second process, call the WebView.setDataDirectorySuffix("dir_name_no_separator") method.

    Get process name:

    public static String getProcessName(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()) {
            if (processInfo.pid == android.os.Process.myPid()) {
                return processInfo.processName;
            }
        }
    
        return null;
    }
    

    Application class onCreate():

    if (!Utils.getProcessName(this).equals("YOUR_SECOND_PROCESS_NAME")) {
        MobileAds.initialize(this);
    } else {
        WebView.setDataDirectorySuffix("dir_name_no_separator")
    }
    
    0 讨论(0)
  • 2020-12-24 02:58

    when error due to ads, then in application class

    try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                val process = getProcessName()
                if (packageName != process) WebView.setDataDirectorySuffix(process)
            }
    
            MobileAds.initialize(this)
            AudienceNetworkAds.initialize(this)
    
        } catch (e: Error) {
            Timber.e(e)
        } catch (e: Exception) {
            Timber.e(e)
        }
    
    0 讨论(0)
  • 2020-12-24 03:14

    To summarize the fix with all the improvements, this is the code in Kotlin:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        if (packageName != Application.getProcessName()) {
            WebView.setDataDirectorySuffix(Application.getProcessName())
        }
    }
    

    Add it to your Application class to onCreate() method.

    Note this is will only fix problem with maximum 2 processes. If your app is using more, you have to provide different WebView suffix for each of them.

    0 讨论(0)
提交回复
热议问题