横竖屏切换时如何处理Dagger组件

9
假设已经在这里提到过,开发人员需要保留组件实例以实现自己的作用域逻辑(因为对于给定组件,作用域方法将返回相同的实例)。
如何在活动生命周期中保持此组件引用的清晰方式是什么?
例如:您正在实现MVP模式,因此您需要一个Presenter来管理Activity。该Presenter可以执行网络操作以下载项目。当设备旋转时,Activity被销毁并重新创建,但是您希望继续进行网络操作并恢复旋转前的Presenter。
通过为提供Presenter的组件提供自定义PerActivity作用域,对组件进行作用域限定是解决方案,因此您必须通过此旋转保留组件实例,以便注入与Activity首次启动时相同的Presenter实例。
我们应该如何处理这个问题?我想到了一种组件缓存的方式(像HashMap一样?),可以由位于Application类中的应用程序组件提供。

2
您的选项包括:- 应用程序中的组件缓存;- 自定义非配置实例;- 保留片段。 - EpicPandaForce
就我个人而言,当当前活动未处于“resume”状态时,我会通过事件总线阻止事件分发,并将Presenter状态放入Bundle中,在事件恢复之前恢复其状态。因此,我的Presenter是无范围的。 - EpicPandaForce
如果Presenter状态是例如使用OkHttp客户端下载数据,您如何将其保存在Bundle中?在这种情况下,似乎需要一个Presenter缓存。 - Rafi Panoyan
1
我认为简短的答案是,如果执行网络操作的逻辑需要比“Activity”实例更长的生命周期,那么它就不是活动范围内的。你能把这个逻辑移到更宽的范围吗? - gk5885
就像我说的那样,通过事件总线进行冻结事件分发。无论如何,这就是我所做的。如果我真的想要保留它,我可能会使用保留片段方法。 - EpicPandaForce
2个回答

0

网络可以与应用程序上下文一起工作。 这是我的设计方式: 使用appscope的Applicationcomponent 现在我会在应用程序层面上创建它 ApplicationComponent应该将上下文作为外部依赖项

接下来是activitycomponent,它扩展了activitymodule,并具有peractivityscope..取决于applicationcomponet

在我的每个活动中,我都会通过提供applicationcomponet来创建activityComponet 可以通过Activity.getapplication().getapplicationcomponent()访问此applicationcomponet

在这里,请确保您的applicationmodule提供的network方法具有appscope 如果是这种情况,即使在应用程序旋转时,您也应该获得相同的network。

查找GitHubapplication示例,将在下一个编辑中发布链接。

此外,值得一看的是livedata(超出本问题的范围)


0

您可以查看ribot/android-boilerplate展示应用的实现。他们选择的解决方案是在BaseActivity中拥有一个static Map<Long, ConfigPersistentComponent>,所有活动都从中扩展。

public class BaseActivity extends AppCompatActivity {

    private static final AtomicLong NEXT_ID = new AtomicLong(0);
    private static final Map<Long, ConfigPersistentComponent> sComponentsMap = new HashMap<>();

    private ActivityComponent mActivityComponent;
    private long mActivityId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Create the ActivityComponent and reuses cached ConfigPersistentComponent if this is
        // being called after a configuration change.
        mActivityId = savedInstanceState != null ?
                savedInstanceState.getLong(KEY_ACTIVITY_ID) : NEXT_ID.getAndIncrement();

        ConfigPersistentComponent configPersistentComponent;
        if (!sComponentsMap.containsKey(mActivityId)) {
            // Creating new component
            configPersistentComponent = DaggerConfigPersistentComponent.builder()
                    .applicationComponent(BoilerplateApplication.get(this).getComponent())
                    .build();
            sComponentsMap.put(mActivityId, configPersistentComponent);
        } else {
            // Reusing component
            configPersistentComponent = sComponentsMap.get(mActivityId);
        }
        mActivityComponent = configPersistentComponent.activityComponent(new ActivityModule(this));
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putLong(KEY_ACTIVITY_ID, mActivityId);
    }

    @Override
    protected void onDestroy() {
        if (!isChangingConfigurations()) {
            // Activity is finishing, removing the component
            sComponentsMap.remove(mActivityId);
        }
        super.onDestroy();
    }

    ...

}

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