[英]ProcessLifecycleOwner not working after updating app compat to to 1.4.1
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.我正在调查一个奇怪的问题,我们将
androidx.appcompat:appcompat
从1.3.1
更改为1.4.1
,突然间我们的LifecycleObservers
观察进程生命周期停止发出任何事件。
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
我也在使用
"androidx.lifecycle:lifecycle-extensions:2.2.0"
,我知道这已经被弃用了,但如果 appcompat 是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.这个 object 被注入
Application
class 并且生命周期观察器被添加,但是onStart
和onStop
永远不会被调用。
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:编辑:根据@EpicPandaForce 的评论,将 Manifest 中的提供程序块更改为:
<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并将
"androidx.lifecycle:lifecycle-extensions:2.2.0"
依赖项替换为"androidx.lifecycle:lifecycle-common:2.4.1"
已解决此问题
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.可以肯定的是,您之所以发生更改,是因为 ProcessLifecycleOwner 的初始化被重新设计为使用依赖于 ContentProvider 的 Jetpack Startup 库,因此仅在进程的主进程中进行初始化。
In the actual code for ProcessLifecycleOwner, it says:在 ProcessLifecycleOwner 的实际代码中,它说:
/** * 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:使其在 2021-03 年使用
androidx.startup
的提交说明了这一点:
"
lifecycle-process
now usesandroidx.startup
to initialize process lifecycle owner."
lifecycle-process
现在使用androidx.startup
来初始化进程生命周期所有者。Previously, this was being done by
androidx.lifecycle.ProcessLifecycleOwnerInitializer
.以前,这是由
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.如果您使用
tools:node="remove"
过去用于初始化流程生命周期的ContentProvider
,那么您需要执行以下操作。<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.因此,您添加的代码段专门禁用了 AndroidX StartUp 进程,因此您的 ProcessLifecycleOwner 不会被初始化。
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.顺便说一句,如果您禁用自动启动过程,Google 没有提供手动安装 ProcessLifecycleOwner 的方法,但要实现它,您只需要模仿他们正在做的事情。 For example, if you needed to use ProcessLifecycleOwner in a multi-process app, then you'd need to not use the ContentProvider.
例如,如果您需要在多进程应用程序中使用 ProcessLifecycleOwner,那么您就不需要使用 ContentProvider。
In that case, you can create a Java file in a package called androidx/lifecycle
:在这种情况下,您可以在名为
androidx/lifecycle
的 package 中创建Java文件:
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.但是在您的位置,您可能只需要删除删除您的 ContentProvider 的代码段。
if you are using lifecyle library, add this如果您使用的是生命周期库,请添加此
def lifecycle_version = "2.5.1"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
There was an upgrade were androidx.lifecycle
started using androidx.startup
to initialize.有一个升级是
androidx.lifecycle
开始使用androidx.startup
进行初始化。 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
.然后您可以完全删除该代码,或使用
tools:node="merge"
而不是remove
。
You need to verify in the Merged Manifest that androidx.lifecycle.ProcessLifecycleInitializer
is being initialized.您需要在 Merged Manifest 中验证
androidx.lifecycle.ProcessLifecycleInitializer
正在初始化。
My workaround might not work for everyone.我的解决方法可能不适用于所有人。 But here's the basic idea.
但这是基本的想法。 Note, my app is using
WorkManager
.请注意,我的应用程序正在使用
WorkManager
。
Change改变
def lifecycle_version = '2.2.0'
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
to到
def lifecycle_version = '2.5.1'
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
Change改变
<!-- https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration -->
<!-- If you want to disable android.startup completely. -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove">
</provider>
to到
<!-- https://developer.android.com/topic/libraries/architecture/workmanager/advanced/custom-configuration -->
<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.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.