課題
一部の端末(例えば Zenfone 3など) でアプリが起動しないという事象が発生している。スタックトレースを見るとWokrManagerのgetInstanceするところでクラッシュしていた。
Caused by: java.lang.IllegalStateException:
at androidx.work.impl.WorkManagerImpl.getInstance (WorkManagerImpl.java:140)
at androidx.work.WorkManager.getInstance (WorkManager.java:180)
どうすればよいか。
原因
WorkManagerImpl.javaのgetInstanceメソッドを参照すると以下のような感じになっている。
https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static @NonNull WorkManagerImpl getInstance(@NonNull Context context) {
synchronized (sLock) {
WorkManagerImpl instance = getInstance();
if (instance == null) {
Context appContext = context.getApplicationContext();
if (appContext instanceof Configuration.Provider) {
initialize(
appContext,
((Configuration.Provider) appContext).getWorkManagerConfiguration());
instance = getInstance(appContext);
} else {
throw new IllegalStateException("WorkManager is not initialized properly. You "
+ "have explicitly disabled WorkManagerInitializer in your manifest, "
+ "have not manually called WorkManager#initialize at this point, and "
+ "your Application does not implement Configuration.Provider.");
}
}
return instance;
}
}
if (appContext instanceof Configuration.Provider) {
がポイントで、ApplicationクラスではConfiguration.Providerを実装していないので通常 false で例外をくらうことになると思うが、
本来はライブラリの方でアプリの起動時にカスタムContentProviderを使用して自身を初期化してくれているため、特に何もしなくても他の端末だとエラーにはならない。
対応1
追記 Sonyの Xperia Z5 Premium(SO-03H)にて同一箇所でクラッシュ発生 。
なぜ駄目なのかが判然としないが、対応1では解決しないらしい。
ApplicationContextでConfiguration.Providerを実装しといてあげればとりあえずクラッシュは避けられそう。
ということでMyApplicationでConfiguration.Provider
をimplementすることに。
getWorkManagerConfiguration
の実装が必要になるが、WorkManagerInitializer.java
内のデフォルト実装にそろえておけばよいだろう。
class MyApplication : MultiDexApplication(), Configuration.Provider {
override fun getWorkManagerConfiguration(): Configuration {
return Configuration.Builder().build()
}
}
対応2
自前で初期化する方法もある。この場合はProvider側でのデフォルト初期化を無効化しておく必要がある(忘れるとクラッシュ)。
<provider
androidname="androidx.work.impl.WorkManagerInitializer"
androidauthorities="${applicationId}.workmanager-init"
toolsnode="remove" />
class MyApplication : MultiDexApplication(), Configuration.Provider {
override fun onCreate() {
WorkManager.initialize(this, Configuration.Builder().build())
}
}
参考
developer.android.com