我是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();
}
我尝试调试应用程序,我认为在加载新配置时,它会创建组件的新实例和演示者的新实例。旋转屏幕时如何保留相同的组件和演示器。非常感谢你!
答案 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”。