Dagger2范围和活动生命周期

时间:2017-01-25 02:36:55

标签: android mvp dagger-2

我有一个Android活动,我正在使用Dagger2注入一个Presenter。即使发生配置更改,我也希望我的Presenter能够保持状态。

例如,我将使用Presenter启动网络呼叫,如果用户在网络呼叫进行中时旋转设备,我希望能够在设备完成后收到响应它的旋转而不必重新启动呼叫。

我被绊倒了,因为如果我将Presenter的实例范围扩展到Activity的生命中,那么在配置更改期间当Activity通过onDestroy()时,Presenter是否有可能被垃圾收集?我的另一个想法是使用在应用程序生命周期内有效的范围。但是,如果我这样做,我如何确保在活动被销毁之后可以对我的Presenter进行垃圾收集(不是因为配置。更改,而是按下了后退按钮)?

有没有办法确保我的Presenter能够在Activity的配置更改后继续存在,并且在应用程序的生命周期内也不会泄露?

2 个答案:

答案 0 :(得分:4)

我强烈反对尝试实施这种方法。

您正在有效地尝试使用DI框架以支持Activity特定的生命周期流程,尽管DI框架不打算像这样使用。

我最近回答了another similar question,其中OP试图在不同Activities之间的View-Model中共享状态。虽然用例不相同,但一般模式是相同的 - 尝试将流控制职责委托给DI框架,这不是一个好主意。

在您的情况下(IMHO)最好的方法是在旋转之前存储当前状态,在旋转时重新实例化演示者,然后恢复其状态。

如何在轮换期间存储状态取决于您要保留的确切内容:

  • 如果您需要保留与UI相关的状态(选择,文本,元素位置等),那么您可以使用通常的onSaveInstanceState()onRestoreInstanceState()回调
  • 如果您需要保留一些与业务相关的状态(正在进行的网络请求,数据,数据修改等),则将此逻辑封装在业务类(例如SomeBusinessUseCaseManager)中,并从Application注入此类带范围的宽组件。

您可以找到Dagger范围here的详细评论。

有关Android中DI的更多信息,请访问here

答案 1 :(得分: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并了解匕首的作用范围。