Dagger2作用域和Activity生命周期

5
我有一个Android Activity,我正在使用Dagger2将Presenter注入其中。我希望我的Presenter能够在发生配置更改时保持状态。
例如,我将使用Presenter启动网络调用,如果用户在网络调用进行中旋转设备,则希望能够在设备完成旋转后接收响应,而无需重新启动调用。
我遇到了困难,因为如果将Presenter的实例范围限定为Activity的生命周期,则Presenter在配置更改期间Activity经历onDestroy()时可能被垃圾回收。我的另一个想法是使用在整个应用程序生命周期内有效的作用域。但是,如果这样做,如何确保一旦Activity已经被永久销毁(不是由于配置更改,而是类似于按下返回按钮之类的原因),我的Presenter就可以被垃圾回收?
是否有一种方法可以确保我的Presenter在Activity的配置更改期间保持存活,并且在应用程序的生命周期内不会泄漏?
2个回答

5
我强烈建议不要尝试实现这种方法。
您实际上是在尝试使用DI框架来支持Activity特定的生命周期流,尽管DI框架并不打算像这样使用。
我最近回答了另一个类似的问题,其中OP尝试在不同的Activities之间共享View-Model中的状态。虽然用例不相同,但一般模式是相同的-尝试将流控制责任委托给DI框架,这不是一个好主意。
在您的情况下,最好的方法(IMHO)是在旋转之前存储当前状态,旋转时重新实例化Presenter,然后恢复其状态。
在旋转期间如何存储状态取决于您要保留什么:
- 如果您需要保留与UI相关的状态(选择、文本、元素位置等),则可以使用通常的onSaveInstanceState()和onRestoreInstanceState()回调。 - 如果您需要保留某些业务相关的状态(进行中的网络请求、数据、数据修改等),则将此逻辑封装在业务类(例如SomeBusinessUseCaseManager)中,并从具有范围的Application组件注入此类。
Dagger的作用域的详细评估可以在此处找到。
有关Android中DI的更多信息,请参见此处

你的第二个建议与我使用Presenter的方式类似。Presenter中注入了几个UseCases(我在Activity中创建UseCase实例,并使用构造函数将其注入到Presenter中)。如果我将UseCase实例化移动到应用程序生命周期内存在的组件中,则UseCase可以在配置更改期间继续工作,并且当在配置更改后创建新的Presenter(作用域为activity)时,它将获得已经运行的UseCases注入。这解决了需要重新启动已经启动的问题。 - neonDion
@neonDion,听起来是个不错的计划。请注意,如果你这样做,你将获得额外的好处,摆脱了演示者和抽象网络相关的东西。这是迈向解耦设计的一大步。 - Vasiliy

0
根据这篇关于自定义范围的文章:

http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/

简而言之,作用域为我们提供了“本地单例”,其生命周期与作用域本身一样长。
仅仅为了明确起见,在Dagger 2中默认没有提供@ActivityScope@ApplicationScope注释。这只是自定义作用域的最常见用法。默认情况下只有@Singleton作用域可用(由Java本身提供),使用作用域并不足够!您必须注意包含该作用域的组件。这意味着在Application类中保留对它的引用,并在Activity更改时重复使用它。
public class GithubClientApplication extends Application {

    private AppComponent appComponent;
    private UserComponent userComponent;

    //...

    public UserComponent createUserComponent(User user) {
        userComponent = appComponent.plus(new UserModule(user));
        return userComponent;
    }

    public void releaseUserComponent() {
        userComponent = null;
    }

    //...
}

你可以查看这个示例项目:

http://github.com/mmirhoseini/marvel

和这篇文章:

https://hackernoon.com/yet-another-mvp-article-part-1-lets-get-to-know-the-project-d3fd553b3e21

为了更熟悉MVP并学习Dagger作用域的工作原理。


你的链接中有很多信息。你能否在回答中添加一个简短的概述,回答以下问题:有没有一种方法可以确保我的Presenter在Activity配置更改时仍然存在,并且在整个应用程序的生命周期内不会泄漏? - neonDion
好的,那么我将编辑答案,但至少看一下这篇文章是必要的,因为它需要知道作用域只是一个标签,不幸的是它们什么也做不了,你必须处理所有内容:http://frogermcs.github.io/dependency-injection-with-dagger-2-custom-scopes/ - Mohsen Mirhoseini

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