更新 AppCompat 到 1.4.1 后,ProcessLifecycleOwner 不工作了。

17

我正在调查一个奇怪的问题,我们将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类中,并且添加了生命周期观察者,但是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的评论,将清单中的提供程序块更改为:

 <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"已解决此问题。


你尝试过使用AppCompat 1.6.0-alpha01版本吗? - F.Mysir
是的,问题出在提供程序块上,它禁用了AndroidX启动过程。 - Jokubas Trinkunas
5个回答

17

很有可能造成你这边发生变化的原因是因为ProcessLifecycleOwner的初始化被重构以使用Jetpack Startup库,该库依赖于ContentProvider,在进程的主进程中进行初始化。

在ProcessLifecycleOwner的实际代码中,它说:

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.
/**
 * 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年3月引入了一个提交,将其使用androidx.startup,该提交的注释如下:

"lifecycle-process现在使用 androidx.startup 来初始化进程 生命周期所有者。

以前,这是由 androidx.lifecycle.ProcessLifecycleOwnerInitializer 完成的。

如果您过去使用 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>

"
所以你添加的代码片段专门禁用了AndroidX启动过程,因此您的ProcessLifecycleOwner将不会被初始化。
顺便说一下,Google没有提供手动安装ProcessLifecycleOwner的方法,但是要实现它,只需要模仿他们的做法。例如,如果您需要在多进程应用程序中使用ProcessLifecycleOwner,则需要不使用ContentProvider。 在这种情况下,您可以在名为androidx / lifecycle的包中创建一个Java文件:
public class ProcessLifecycleInitializerAccessor {
    public static LifecycleOwner initialize(Application context) {
        LifecycleDispatcher.init(context);
        ProcessLifecycleOwner.init(context);
        return ProcessLifecycleOwner.get();
    }
}

但是在您的情况下,您只需要删除删除ContentProvider的代码片段。


1
更新提供程序块已经解决了这个问题,谢谢。 - Jokubas Trinkunas
1
请从ProcessLifecycleInitializer元数据中删除tools:node="remove",否则应用程序将崩溃。请更新您的答案@EpicPandaForce。 - Murat
@Murat 正确,已更新。 - EpicPandaForce
@EpicPandaForce,我在想我们如何访问android/lifecycle并添加上述类? - droidev
1
@droidev,你创建了一个名为android的包,其中包含一个名为lifecycle的子包,那么如果你创建了一个Java类,它可以访问这些函数,因为它们仅仅是包内部的。 - EpicPandaForce

8

有一个升级,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


7

如果您正在使用Lifecycle库,请添加以下内容

def lifecycle_version = "2.5.1"    
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

4

我的解决方法可能不适用于所有人。但这里是基本的思路。请注意,我的应用正在使用WorkManager

步骤1:

更改

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"

步骤2:
更改
<!-- 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>

为了

<!-- 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>

1
我在禁用数据绑定时遇到了这个问题。
添加这个解决了它。
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接