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-processnow usesandroidx.startupto initialize process lifecycle owner.Previously, this was being done by
androidx.lifecycle.ProcessLifecycleOwnerInitializer.If you used
tools:node="remove"theContentProviderbeing 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.
There was an upgrade were androidx.lifecycle started using androidx.startup to initialize.
So, if this code was in your manifest:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
Then you can completely remove that code, or use tools:node="merge" instead of remove.
You need to verify in the Merged Manifest that androidx.lifecycle.ProcessLifecycleInitializer is being initialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With