Android Pie(API 28)から、Googleは2つの異なるプロセスで単一のWebViewインスタンスを使用することを許可していません。
必要に応じて、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回呼び出したわけでも、メインプロセスで呼び出したわけでもありません。何か案は?
解決しました。
私のプロジェクトは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")
}