将应用程序兼容性更新为 1.4.1 后,ProcessLifecycleOwner 无法正常工作

ProcessLifecycleOwner not working after updating app compat to to 1.4.1

我正在调查一个奇怪的问题,我们将 androidx.appcompat:appcompat1.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 并且添加了生命周期观察器,但从未调用 onStartonStop

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 正在初始化。