I'm investigating a weird issue, where we changed the androidx.appcompat:appcompat
from 1.3.1
to 1.4.1
and all of a sudden our LifecycleObservers
observing process lifecycle stopped emitting any events.
I'm also using "androidx.lifecycle:lifecycle-extensions:2.2.0"
, I know that this is already deprecated, but it works flawlessly if appcompat is 1.3.1
I have set the correct application name in the Manifest, I have included this provider as required per docs.
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
Example of initialisation, which doesn't work. This object is injected in the Application
class and lifecycle observer is getting added, but onStart
and onStop
are never called.
class AppLifecycle @Inject constructor(
private val foregroundProxy: AppLifecycleProxy
) : LifecycleObserver {
init {
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
foregroundProxy.onStarted()
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
foregroundProxy.onStopped()
}
}
EDIT: As per @EpicPandaForce comment, changing the the provider block in Manifest to:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities=\"${applicationId}.androidx-startup"
android:exported="false"
tools:node=\"merge">
<!-- If you are using androidx.startup to initialize other components -->
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
And replacing the "androidx.lifecycle:lifecycle-extensions:2.2.0"
dependency with "androidx.lifecycle:lifecycle-common:2.4.1"
has fixed this problem
There's a good bet that the reason there has been changes on your side is because ProcessLifecycleOwner's initialization was reworked to use the Jetpack Startup library, which relies on a ContentProvider, therefore only does initialization in a process's main process.
In the actual code for ProcessLifecycleOwner, it says:
/** * Initializes {@link ProcessLifecycleOwner} using {@code androidx.startup}. */ public final class ProcessLifecycleInitializer implements Initializer<LifecycleOwner> { @NonNull @Override public LifecycleOwner create(@NonNull Context context) { AppInitializer appInitializer = AppInitializer.getInstance(context); if (!appInitializer.isEagerlyInitialized(getClass())) { throw new IllegalStateException( "ProcessLifecycleInitializer cannot be initialized lazily. \n" + "Please ensure that you have: \n" + "<meta-data\n" + " android:name='androidx.lifecycle.ProcessLifecycleInitializer' \n" + " android:value='androidx.startup' /> \n" + "under InitializationProvider in your AndroidManifest.xml"); } LifecycleDispatcher.init(context); ProcessLifecycleOwner.init(context); return ProcessLifecycleOwner.get(); } @NonNull @Override public List<Class<? extends Initializer<?>>> dependencies() { return Collections.emptyList(); } }
And the commit that made it use androidx.startup
in 2021-03 says this:
"
lifecycle-process
now usesandroidx.startup
to initialize process lifecycle owner.Previously, this was being done by
androidx.lifecycle.ProcessLifecycleOwnerInitializer
.If you used
tools:node="remove"
theContentProvider
being used to initialize process lifecycle in the past, then you need to do the following instead.<provider android:name="androidx.startup.InitializationProvider" android:authorities=\"${applicationId}.androidx-startup" android:exported="false" tools:node=\"merge"> <!-- If you are using androidx.startup to initialize other components --> <meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup" /> </provider>
(or) <!-- If you want to disable androidx.startup completely. --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" tools:node="remove"> </provider> "
So the snippet you added specifically disables the AndroidX StartUp process and therefore your ProcessLifecycleOwner won't get initialized.
By the way, Google did NOT provide a way to manually install the ProcessLifecycleOwner if you disable the automatic start-up process, but to achieve it, you just need to mimic what they are doing. For example, if you needed to use ProcessLifecycleOwner in a multi-process app, then you'd need to not use the ContentProvider.
In that case, you can create a Java file in a package called androidx/lifecycle
:
public class ProcessLifecycleInitializerAccessor {
public static LifecycleOwner initialize(Application context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init(context);
return ProcessLifecycleOwner.get();
}
}
But in your place, you probably just have to remove the snippet that removes your ContentProvider.