web-dev-qa-db-ja.com

Android Pie(9.0)マルチプロセスのWebView

Android Pie(API 28)から、Googleは2つの異なるプロセスで単一のWebViewインスタンスを使用することを許可していません。

ドキュメント: https://developer.Android.com/reference/Android/webkit/WebView.html#setDataDirectorySuffix(Java.lang.String)

必要に応じて、WebView.setDataDirectorySuffix("dir_name_no_separator")を呼び出しましたが、残念ながら例外が発生します。 2番目のプロセスサービスonCreate()内でこのメソッドを呼び出そうとしました。

Java.lang.RuntimeException: Unable to create service com.myapp.service.MyService: Java.lang.IllegalStateException: Can't set data directory suffix: WebView already initialized
        at Android.app.ActivityThread.handleCreateService(ActivityThread.Java:3544)
        at Android.app.ActivityThread.access$1300(ActivityThread.Java:199)
        at Android.app.ActivityThread$H.handleMessage(ActivityThread.Java:1666)
        at Android.os.Handler.dispatchMessage(Handler.Java:106)
        at Android.os.Looper.loop(Looper.Java:193)
        at Android.app.ActivityThread.main(ActivityThread.Java:6669)
        at Java.lang.reflect.Method.invoke(Native Method)
        at com.Android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.Java:493)
        at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:858)
     Caused by: Java.lang.IllegalStateException: Can't set data directory suffix: WebView already initialized
        at Android.webkit.WebViewFactory.setDataDirectorySuffix(WebViewFactory.Java:136)
        at Android.webkit.WebView.setDataDirectorySuffix(WebView.Java:2165)
        at com.myapp.service.MyService.onCreate(MyService.Java:134)

私はその例外の理由を見つけることができませんでした。このメソッドを2回呼び出したわけでも、メインプロセスで呼び出したわけでもありません。何か案は?

12
Lior Iluz

解決しました。

私のプロジェクトはAdMob広告をホストし、ApplicationクラスMobileAds.initialize()内でonCreate()メソッドを呼び出します。広告イニシャライザはWebViewをロードします。これは、WebView.setDataDirectorySuffix("dir_name_no_separator")メソッドを呼び出す前の新しいプロセスでの実行が禁止されています。

2番目のプロセスが作成されると、同じアプリケーション作成フローも実行されます。つまり、Applicationクラス内で同じonCreate()を呼び出します。これは、新しいWebViewインスタンスを作成するMobileAds.initialize()それがクラッシュの原因です。

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

これをどのように解決しましたか?

以下のメソッドを使用してプロセス名を取得し、それがメインプロセスであるかどうかを確認します。MobileAds.initialize()メソッドを呼び出し、2番目のプロセスである場合はWebView.setDataDirectorySuffix("dir_name_no_separator")メソッドを呼び出します。

プロセス名を取得:

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;
}

アプリケーションクラスonCreate():

if (!Utils.getProcessName(this).equals("YOUR_SECOND_PROCESS_NAME")) {
    MobileAds.initialize(this);
} else {
    WebView.setDataDirectorySuffix("dir_name_no_separator")
}
11
Lior Iluz