将应用程序兼容性更新为 1.4.1 后,ProcessLifecycleOwner 无法正常工作
ProcessLifecycleOwner not working after updating app compat to to 1.4.1
我正在调查一个奇怪的问题,我们将 androidx.appcompat:appcompat
从 1.3.1
更改为 1.4.1
突然间我们的 LifecycleObservers
观察进程生命周期停止发出任何事件。
我也在使用 "androidx.lifecycle:lifecycle-extensions:2.2.0"
,我知道这已经被弃用了,但是如果 appcompat 是 1.3.1
它就可以完美地工作
我已经在清单中设置了正确的应用程序名称,我已经按照文档的要求包含了这个提供程序。
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
初始化示例,无效。该对象被注入 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()
}
}
编辑:
根据@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>
将 "androidx.lifecycle:lifecycle-extensions:2.2.0"
依赖项替换为 "androidx.lifecycle:lifecycle-common:2.4.1"
已解决此问题
可以肯定的是,您这边发生变化的原因是 ProcessLifecycleOwner 的初始化被重新设计为使用依赖于 ContentProvider 的 Jetpack Startup 库,因此只在进程的主进程中进行初始化。
在 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();
}
}
并且在 2021-03 年使用 androidx.startup
的提交是这样说的:
"lifecycle-process
now uses androidx.startup
to initialize process
lifecycle owner.
Previously, this was being done by
androidx.lifecycle.ProcessLifecycleOwnerInitializer
.
If you used tools:node="remove"
the ContentProvider
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" tools:node="remove" />
</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>
"
所以您添加的代码片段专门禁用了 AndroidX 启动进程,因此您的 ProcessLifecycleOwner 不会被初始化。
顺便说一下,如果您禁用自动 start-up 进程,Google 没有提供手动安装 ProcessLifecycleOwner 的方法,但要实现它,您只需要模仿他们正在做的事情.例如,如果您需要在 multi-process 应用程序中使用 ProcessLifecycleOwner,则不需要使用 ContentProvider。
在这种情况下,您可以在名为 androidx/lifecycle
的包中创建一个 Java 文件:
public class ProcessLifecycleInitializerAccessor {
public static LifecycleOwner initialize(Application context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init(context);
return ProcessLifecycleOwner.get();
}
}
但在您的位置,您可能只需要删除删除您的 ContentProvider 的代码段。
有一个升级 androidx.lifecycle
开始使用 androidx.startup
进行初始化。
因此,如果此代码在您的清单中:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
然后您可以完全删除该代码,或者使用 tools:node="merge"
而不是 remove
。
您需要在合并清单中验证 androidx.lifecycle.ProcessLifecycleInitializer
正在初始化。
我正在调查一个奇怪的问题,我们将 androidx.appcompat:appcompat
从 1.3.1
更改为 1.4.1
突然间我们的 LifecycleObservers
观察进程生命周期停止发出任何事件。
我也在使用 "androidx.lifecycle:lifecycle-extensions:2.2.0"
,我知道这已经被弃用了,但是如果 appcompat 是 1.3.1
我已经在清单中设置了正确的应用程序名称,我已经按照文档的要求包含了这个提供程序。
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
初始化示例,无效。该对象被注入 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()
}
}
编辑: 根据@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>
将 "androidx.lifecycle:lifecycle-extensions:2.2.0"
依赖项替换为 "androidx.lifecycle:lifecycle-common:2.4.1"
已解决此问题
可以肯定的是,您这边发生变化的原因是 ProcessLifecycleOwner 的初始化被重新设计为使用依赖于 ContentProvider 的 Jetpack Startup 库,因此只在进程的主进程中进行初始化。
在 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(); } }
并且在 2021-03 年使用 androidx.startup
的提交是这样说的:
"
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" tools:node="remove" /> </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> "
所以您添加的代码片段专门禁用了 AndroidX 启动进程,因此您的 ProcessLifecycleOwner 不会被初始化。
顺便说一下,如果您禁用自动 start-up 进程,Google 没有提供手动安装 ProcessLifecycleOwner 的方法,但要实现它,您只需要模仿他们正在做的事情.例如,如果您需要在 multi-process 应用程序中使用 ProcessLifecycleOwner,则不需要使用 ContentProvider。
在这种情况下,您可以在名为 androidx/lifecycle
的包中创建一个 Java 文件:
public class ProcessLifecycleInitializerAccessor {
public static LifecycleOwner initialize(Application context) {
LifecycleDispatcher.init(context);
ProcessLifecycleOwner.init(context);
return ProcessLifecycleOwner.get();
}
}
但在您的位置,您可能只需要删除删除您的 ContentProvider 的代码段。
有一个升级 androidx.lifecycle
开始使用 androidx.startup
进行初始化。
因此,如果此代码在您的清单中:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />
然后您可以完全删除该代码,或者使用 tools:node="merge"
而不是 remove
。
您需要在合并清单中验证 androidx.lifecycle.ProcessLifecycleInitializer
正在初始化。