将应用程序兼容性更新到 1.4.1 后 ProcessLifecycleOwner 无法工作

发布于 2025-01-14 09:25:59 字数 1800 浏览 4 评论 0原文

我正在调查一个奇怪的问题,我们将 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" 已修复此问题

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

真心难拥有 2025-01-21 09:25:59

很有可能,您这边发生更改的原因是因为 ProcessLifecycleOwner 的初始化被重新设计为使用 Jetpack Startup 库,该库依赖于 ContentProvider,因此仅在进程的主进程中进行初始化。

在 ProcessLifecycleOwner 的实际代码中,它表示:

<前><代码>/**
* 使用 {@code androidx.startup} 初始化 {@link ProcessLifecycleOwner}。
*/
公共最终类 ProcessLifecycleInitializer 实现 Initializer; {

@非空
@覆盖
公共 LifecycleOwner create(@NonNull Context context) {
AppInitializer appInitializer = AppInitializer.getInstance(context);
if (!appInitializer.isEagerlyInitialized(getClass())) {
抛出新的 IllegalStateException(
“ProcessLifecycleInitializer 无法延迟初始化。\n”
+“请确保您有:\n”
+ "<元数据\n"
+ " android:name='androidx.lifecycle.ProcessLifecycleInitializer' \n"
+ " android:value='androidx.startup' //> \n"
+“在 AndroidManifest.xml 中的 InitializationProvider 下”);
}
LifecycleDispatcher.init(上下文);
ProcessLifecycleOwner.init(上下文);
返回 ProcessLifecycleOwner.get();
}

@非空
@覆盖
公共列表<类<?扩展初始化器>>依赖项(){
返回 Collections.emptyList();
}
}

在 2021 年 3 月使用 androidx.startup 的提交内容如下:

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

以前,这是由
androidx.lifecycle.ProcessLifecycleOwnerInitializer

如果您使用了tools:node="remove",则ContentProvider用于
初始化过去的流程生命周期,然后您需要执行以下操作
以下为替代。

<前><代码><提供商
android:name="androidx.startup.InitializationProvider"
android:authorities=\"${applicationId}.androidx-startup"
android:exported="false" 工具:node=\"merge">
<元数据
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />

<前><代码>
(或者)

因此,您专门添加的代码片段会禁用 AndroidX StartUp 进程,因此您的 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 的代码片段。

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-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" /> 
</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.

空袭的梦i 2025-01-21 09:25:59

使用 androidx.startup 进行初始化时,androidx.lifecycle 开始了升级。
因此,如果此代码位于您的清单中:

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    tools:node="remove" />

那么您可以完全删除该代码,或使用 tools:node="merge" 而不是 remove

您需要在合并清单中验证 androidx.lifecycle.ProcessLifecycleInitializer 是否正在初始化。

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.

南冥有猫 2025-01-21 09:25:59

如果您使用生命周期库,请添加此

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

if you are using lifecyle library, add this

def lifecycle_version = "2.5.1"    
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
污味仙女 2025-01-21 09:25:59

我的解决方法可能并不适合所有人。但这是基本的想法。请注意,我的应用程序正在使用 WorkManager

步骤 1:

更改

def lifecycle_version = '2.2.0'
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

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>

My workaround might not work for everyone. But here's the basic idea. Note, my app is using WorkManager.

Step 1:

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"

Step 2:

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>
天荒地未老 2025-01-21 09:25:59

当我禁用数据绑定时,我遇到了这个问题。

添加这个就解决了

implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"

I got this problem when I disabled databinding.

Adding this solved it

implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文