Вызовите WorkManagerImpl.getInstance в background.systemjob.SystemJobService.onCreate reason java.lang.IllegalStateException - PullRequest
1 голос
/ 24 июня 2019

Мы используем следующую библиотеку WorkManager

def work_version = "2.1.0-beta01"
implementation "androidx.work:work-runtime:$work_version"

Наш класс Application изменяется следующим образом, чтобы он хорошо работал с WorkManager

public class WeNoteApplication extends MultiDexApplication implements DefaultLifecycleObserver, Configuration.Provider {

    private static WeNoteApplication me;

    @Override
    public void onCreate() {
        super.onCreate();

        me = this;

        ...
    }

   public static WeNoteApplication instance() {
        return me;
    }

    @NonNull
    @Override
    public Configuration getWorkManagerConfiguration() {
        return new Configuration.Builder()
                .build();
    }
}

Мы не добавляем код WorkManager, связанный с AndroidManifest.xml.Мы исключительно полагаемся на Инициализация по умолчанию


Так мы строим WorkManager

public static WorkManager getWorkManager() {
    WeNoteApplication weNoteApplication = WeNoteApplication.instance();
    return WorkManager.getInstance(weNoteApplication);
}

Вышеприведенная функция вызывается в 4 разных местах

  1. Activity
  2. Fragment
  3. BroadcastReceiver
  4. IntentService

Все еще,мы получаем следующий аварийный журнал в производстве.Это происходит в Android 7.1, Android 8.1, Android 9 (пока)

java.lang.RuntimeException: 
  at android.app.ActivityThread.handleCreateService (ActivityThread.java:3265)
  at android.app.ActivityThread.-wrap5 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1598)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:241)
  at android.app.ActivityThread.main (ActivityThread.java:6274)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776)
Caused by: java.lang.IllegalStateException: 
  at androidx.work.impl.WorkManagerImpl.getInstance (WorkManagerImpl.java:142)
  at androidx.work.impl.background.systemjob.SystemJobService.onCreate (SystemJobService.java:53)
  at android.app.ActivityThread.handleCreateService (ActivityThread.java:3255)
  at android.app.ActivityThread.-wrap5 (ActivityThread.java)
  at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1598)
  at android.os.Handler.dispatchMessage (Handler.java:102)
  at android.os.Looper.loop (Looper.java:241)
  at android.app.ActivityThread.main (ActivityThread.java:6274)
  at java.lang.reflect.Method.invoke (Method.java)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:886)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:776)

Как вы можете видеть в аварии, авария происходит из WorkManager изнутри, а не из нашего приложения.

Глядя на https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager/src/main/java/androidx/work/impl/WorkManagerImpl.java#142

WorkManagerImpl

/**
 * Retrieves the singleton instance of {@link WorkManagerImpl}.
 *
 * @param context A context for on-demand initialization.
 * @return The singleton instance of {@link WorkManagerImpl}
 * @hide
 */
@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.");
            }

Существует 2 возможности IllegalStateException

  1. appContext, равных нулю,(Как это может быть null?)
  2. appContext не реализует Configuration.Provider (Но мы уже реализуем Configuration.Provider в нашем WeNoteApplication?)

Чтобы выяснить,как контекст передается в WorkManagerImpl из SystemJobService, мы смотрим на код androidx.work.impl.background.systemjob.SystemJobService.onCreate - https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/work/workmanager/src/main/java/androidx/work/impl/background/systemjob/SystemJobService.java#53

SystemJobService

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@RequiresApi(WorkManagerImpl.MIN_JOB_SCHEDULER_API_LEVEL)
public class SystemJobService extends JobService implements ExecutionListener {
    private static final String TAG = Logger.tagWithPrefix("SystemJobService");
    private WorkManagerImpl mWorkManagerImpl;
    private final Map<String, JobParameters> mJobParameters = new HashMap<>();
    @Override
    public void onCreate() {
        super.onCreate();
        mWorkManagerImpl = WorkManagerImpl.getInstance(getApplicationContext());

Сначала хорошо выглядитвзгляд.Но почему WorkManagerImpl не может получить Configuration.Provider, хотя я уже внедрил Configuration.Provider в моем Application?Это потому, что я использую MultiDexApplication?


Поиск

В SystemJobService он может ожидать значение null и может допускать нулевое значение из WorkManagerImpl.getInstance из-за автоматическое резервное копирование причина.

@Override
public void onCreate() {
    super.onCreate();
    mWorkManagerImpl = WorkManagerImpl.getInstance(getApplicationContext());
    if (mWorkManagerImpl == null) {
        // This can occur if...
        // 1. The app is performing an auto-backup.  Prior to O, JobScheduler could erroneously
        //    try to send commands to JobService in this state (b/32180780).  Since neither
        //    Application#onCreate nor ContentProviders have run, WorkManager won't be
        //    initialized.  In this case, we should ignore all JobScheduler commands and tell it
        //    to retry.

Но, текущая реализация WorkManagerImpl.getInstance(Context context) такова, что она никогда не вернет ноль, а выдаст IllegalStateException.

Разве нет конфликта междуэти 2 SystemJobService.onCreate логика и WorkManagerImpl.getInstance логика?


система отслеживания проблем

Я отправил свое замечание https://issuetracker.google.com/issues/135858602

1 Ответ

1 голос
/ 27 июня 2019

Это ошибка. Исправление будет доступно в WorkManager 2.1.0-rc01 позже на этой неделе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...