防止Dagger2组件在屏幕旋转时重新创建

时间:2017-12-03 17:26:20

标签: android dagger-2 android-mvp dagger

我是Dagger2依赖注入的新手。旋转屏幕时,我有一些困难要保留相同的组件。

@Inject
MainActivityPresenterImpl presenter;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    component = DaggerMainActivityComponent.builder()
            .mainActivityModule(new MainActivityModule(this))
            .applicationComponent(TrainningDagger3.get(this).getComponent())
            .build();
    component.inject(this);
    presenter.fetchData();
}

我尝试调试应用程序,我认为在加载新配置时,它会创建组件的新实例和演示者的新实例。旋转屏幕时如何保留相同的组件和演示器。非常感谢你!

2 个答案:

答案 0 :(得分:2)

您必须决定是否希望在屏幕旋转时销毁和重新创建您的活动(即"配置更改")。如果您想自己处理它,我建议您只需在AndroidManifest.xml中进行更改;如果你想通过Dagger处理它,你需要将数据保存在一个寿命较长的对象(例如你的ApplicationComponent)中。

the official docs on "Handling Configuration Changes"一样,您可以指示您的Activity只是处理方法调用而不是重新启动:

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden"
          android:label="@string/app_name">
     

现在,当其中一个配置发生更改时,MyActivity不会重新启动。相反,MyActivity会收到对onConfigurationChanged()的调用。此方法传递Configuration对象,该对象指定新设备配置。通过读取Configuration中的字段,您可以确定新配置并通过更新界面中使用的资源进行适当的更改。

重要的是,这允许您使ActivityComponent保持与Activity本身一样长寿,并且可以更好地推断您的Activity实例何时有效或陈旧。您仍然需要为Android的多任务处理加载和保存数据,但无论您如何使用Dagger都是如此。

如果您认为在配置更改时销毁和重新创建活动很重要,那很好,但我会提醒您不要使用术语&#34;活动组件&#34;如果您正在创建或修改组件,使其的活动时间长于单个活动实例。这将是该术语的非典型用法,对其他开发人员来说可能会非常混乱。相反,如果您希望Dagger组件为多个Activity实例(多个活动类或同一活动的多个实例)创建和保持状态,则应考虑将这些对象放入现有的ApplicationComponent,或创建新组件(例如, &#34; SessionComponent&#34;)长于一个ActivityComponent但短于ApplicationComponent 。如果你这样做,你需要非常小心,这个对象中的任何东西都不能保存在Activity实例,View或任何与单个Activity永久关联的东西上:这会导致内存泄漏,因为Android不会当SessionComponent或ApplicationComponent保存对它的引用时,能够对Activity的那些部分进行垃圾收集。

答案 1 :(得分:0)

创建一个Application类并将Daggger初始化移动到Application类的onCreate()方法。通过这样做,您的匕首初始化将遍历您的应用程序范围。

您遇到的这个问题是因为您的活动被销毁,并且如果更改了方向,则会创建新活动。因此,在Activity的onCreate方法中初始化匕首不是正确的方法。

并确保在匕首@provides方法中添加@singleton。

public class MainApplication extends Application {
@Override
public void onCreate() {
    super.onCreate();
    mainApplication = this;
    component = DaggerMainActivityComponent.builder()
            .mainActivityModule(new MainActivityModule(this))
            .applicationComponent(TrainningDagger3.get(this).getComponent())
            .build();
}

并且不要忘记在manifest的应用程序标记中添加 android:name =“。MainApplication”