WorkManager - Should we remove the default initializer, when we use both Default initialization and Custom initialization?

We introduced this lint rule in WorkManager 2.3.0-*. The problem we are trying to address with this Lint rule is that if you have both the WorkManagerInitializer ContentProvider and your Application subtype implements Configuration.Provider (for on-demand initialization) - the ContentProvider will always take precedence.

This might be unexpected, especially when you have additional Configuration which will not take effect because the ContentProvider always uses the default configuration.

All you really need to do is to remove the default provider. That way initialization will no longer be eager, but be on-demand.


Yes you need to remove the default work manager initializer as you did if you want to use on-demand initialization, so keep the following piece of code in your manifest:

<provider
   android:name="androidx.work.impl.WorkManagerInitializer"
   android:authorities="${applicationId}.workmanager-init"
   tools:node="remove" />

Also the above documentation clearly state that you should not be calling WorkManager.getInstance() (without the Context argument):

Note: If you call the deprecated no-parameter WorkManager.getInstance() method before WorkManager has been initialized, the method throws an exception. You should always use the WorkManager.getInstance(Context) method, even if you're not customizing WorkManager.

After looking at the androix/work changelog you will see that a new feature was added in version 2.3.0-beta02:

  • Added a lint rule which ensures that the content provider androidx.work.impl.WorkManagerInitializer is removed from the AndroidManifest.xml when using on demand initialization. (aosp/1167007)

The reason why you have this error after upgrading from version 2.2.0 to 2.3.0.rc1 is because, the android team added a RemoveWorkManagerInitializerDetector that would throw the exception you got in the following pull request at build time.

Now about the source code, I suggest you tight the getWorkManager method to the application directly like below:

import androidx.annotation.NonNull;
import androidx.work.Configuration;
import androidx.work.WorkManager;

public class App extends MultiDexApplication implements Configuration.Provider {
    private static App APP_INSTANCE;

    @Override
    public void onCreate() {
        super.onCreate();
        APP_INSTANCE = this;
    }

    public static App getInstance() {
        return APP_INSTANCE;
    }

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

    public static WorkManager getWorkManager() {
        return WorkManager.getInstance(APP_INSTANCE);
    }
}

And just call App.getWorkManager() whenever you need to in the app source code

You could do something equivalent for your ContentProvider if there is any.

PS: Interesting codelabs tutorials exits for java or kotlin