防止 Dagger 2 组件在屏幕上旋转

Prevent Dagger2 component from recreating on screen rotation

我是 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();
}

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

创建应用程序 class 并将 Daggger 初始化移至应用程序 class 的 onCreate() 方法。通过这样做,你的匕首初始化贯穿你的应用程序范围。

您遇到的这个问题是因为您的 Activity 被破坏,如果方向改变,则会创建新的 activity。所以在 Activity 的 onCreate 方法中初始化 dagger 并不是正确的方法。

并确保在 dagger @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();
}

并且不要忘记在清单的应用程序标签中添加 android:name=".MainApplication"

您将不得不决定是否希望 Activity 在屏幕旋转时被销毁并重新创建(即“配置更改”)。如果您想自己处理,我建议您只需在 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">

Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration. By reading fields in the Configuration, you can determine the new configuration and make appropriate changes by updating the resources used in your interface.

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

如果您认为在配置更改时销毁并重新创建您的 Activity 很重要,那很好,但如果您正在创建或将组件修改为 比单个 Activity 实例 的寿命更长。那将是该术语的非典型用法,并且可能会让其他开发人员感到困惑。相反,如果您希望 Dagger 组件为多个 Activity 实例(多个 activity 类 或相同 activity 的多个实例)创建和保存状态,您应该考虑将这些对象放入您现有的 ApplicationComponent 中,或者创建一个新组件(例如“SessionComponent”),它比一个 ActivityComponent 长,但比您的 ApplicationComponent 短。如果你这样做,你需要非常小心,这个对象中的任何东西都不能保存在 Activity 实例、视图或任何与单个 Activity 永久关联的东西上:这会导致内存泄漏,因为当您的 SessionComponent 或 ApplicationComponent 持有对它的引用时,Android 将无法垃圾收集 Activity 的那些片段。