3

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

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

4

2 回答 2

2

您将不得不决定是否要在屏幕旋转时销毁并重新创建 Activity(即“配置更改”)。如果您想自己处理,我建议您只需在 AndroidManifest.xml 中进行更改;如果你想通过 Dagger 来处理它,你需要将你的数据保存在一个寿命更长的对象中(比如你的 ApplicationComponent)。

正如在“处理配置更改”的官方文档中一样,您可以指示您的 Activity 简单地处理方法调用而不是重新启动:

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

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

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

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

于 2017-12-05T18:56:20.080 回答
0

创建一个 Application 类并将 Dagger 初始化移动到 Application 类的 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" 。

于 2017-12-03T17:53:38.573 回答