Android Pie (9.0) WebView in multi-process



从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")但不幸的是,我得到了一个例外。 我尝试在第二个进程服务 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)

我找不到任何例外的原因。我没有两次调用此方法,也没有在主进程中调用它。有什么想法吗?

已解决。

我的项目托管了 AdMob 广告,我在Application类中调用了MobileAds.initialize()方法onCreate()。ads 初始值设定项加载一个WebView现在禁止在新进程中执行该WebView.setDataDirectorySuffix("dir_name_no_separator"),然后再调用 方法。

创建第二个进程时,它还会经历相同的应用程序创建流,这意味着它会调用Application类中的相同onCreate(),该类调用尝试创建新的WebView实例的MobileAds.initialize(),从而导致崩溃。

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

我是如何解决这个问题的?

我使用以下方法获取进程名称并检查它是否是我的主进程 - 调用 MobileAds.initialize(( 方法,如果这是我的第二个进程,请调用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")
}

总结修复程序的所有改进,这是 Kotlin 中的代码:

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

将其添加到Application类中以onCreate()方法。

请注意,这只会解决最多 2 个进程的问题。如果你的应用使用更多,则必须为每个应用提供不同的 WebView 后缀。

当由于广告导致错误时,则在应用程序类中

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

相关内容

  • 没有找到相关文章

最新更新