java – 带有MVP的Dagger 2,避免在视图重新创建时创建额外的presenter对象
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 带有MVP的Dagger 2,避免在视图重新创建时创建额外的presenter对象,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4588字,纯文字阅读大概需要7分钟。
内容图文
![java – 带有MVP的Dagger 2,避免在视图重新创建时创建额外的presenter对象](/upload/InfoBanner/zyjiaocheng/701/228553cffa8f48b0b9ad0970cb5e3e07.jpg)
我有一个应用程序实现MVP模式与一个Loader来维护视图娱乐上的演示者对象(有一篇关于这个here的文章).我是Dagger 2的新手,试图与当前代码一起实现它.
我已经设法使它工作,但现在我的演示者创建了两次.起初它是使用在onCreateLoader中初始化的工厂类创建的,但是当添加Dagger 2实现时,我创建了两个对象(在工厂类和注入时).
现在我避免在onCreateLoader中创建一个新的演示者,而是传递注入的演示者.问题在于视图重新创建:每次销毁和重新创建视图时,都会在OnCreate / OnCreateView中注入一个新的演示者.这是场景:
>注入新的演示者:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
getControllerComponent().inject(this);
...
}
>初始化Loader,如果Loader不存在,则调用onCreateLoader.请注意,我们通过了注入的演示者:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getLoaderManager().initLoader(PRESENTER_LOADER_ID, null, this);
}
@Override
public Loader<MyPresenter> onCreateLoader(int id, Bundle args) {
switch (id) {
case PRESENTER_LOADER_ID:
return new PresenterLoader<>(getContext(), presenter);
//return new PresenterLoader<>(getContext(), new MyPresenterFactory());
}
return null;
}
>分配从装载程序收到的演示者.如果它刚刚创建,我们分配已经分配的相同对象,所以没有任何反应.但是,如果视图被重新创建,那么Dagger 2会注入一个新的演示者,在这里我们扔掉新的演示者并将其替换为Loader中的旧演示者.
@Override
public void onl oadFinished(Loader<MyPresenter> loader, MyPresenter data) {
this.presenter = data;
}
我想维护演示者实例,这就是我想要发生的事情.我的问题是在每个视图重新创建一个冗余的presenter对象.首先,它是不必要的,此外,视图在加载完成之前持有对不同演示者的引用.显然我在这段时间内没有使用演示者(在注入之后和负载完成之前),但我绝对不喜欢它,并担心这个新的演示者将来会被错误地使用.
Dagger 2专家,有没有一种方法可以在第一次创建演示者时(在Loader创建之前)但是在观看娱乐时避免使用它?非常感谢!
解决方法:
首先我只想提一下,如果你注入你的演示者,你不应该在以后从你的装载机再次分配它.
使用注入来提供对象,或者自己提供.如果你同时做这两件事,你就有可能引入bug.
is there a way to create the presenter the first time (before Loader is created) but avoid it on view recreation?
tl; dr您需要一个演示者的作用域,它反映了组件的生命周期,这可能会在配置更改后继续存在.此范围不得保留对Activitys Context的任何引用.
组件遵循一些生命周期.您通常会在Application中保留一些@Singleton注释组件,以及您为每个Activity创建的一些@PerActivity或类似范围的组件,这些组件将在(或应该)在活动进行配置更改时重新创建,因为这些依赖项通常引用活动上下文应该与Activity一起生存和死亡.
您面临的主要问题是范围问题.
如果您的演示者没有范围,您将在每次请求演示者时重新创建一个新的演示者,只要您将其注入其他地方,就会无意中导致错误.通常,演示者会保留在活动中,并且通常由某些@PerActivity范围确定范围.
如果您的演示者是@PerActivity范围的一部分,它应该(与所有其他@PerActivity依赖关系一样)与所有其他依赖关系一起重新创建.如果保留演示者,但重新创建所有其他对象,旧演示者仍将引用旧依赖项,从而造成内存泄漏. Scoped对象应该只存在于自己的范围内.
同一作用域中的对象可以相互引用,从而使一个作用域对象在其作用域之外保持活动也会无意中导致错误,内存泄漏等.
因此,您不希望将此演示者保留在Loader中.
另一方面,如果你说No,那个演示者在层次结构中高出一步,是@PerScreen的一部分,在那里我保留了更长的生活对象,那么你需要找到一种方法来实际保持这个@PerScreen组件在@PerActivity组件中保持活着状态将与活动一起重新创建.
假设以下范围层次结构:
`X > Y` read X is subcomponent of Y
@Singleton > @PerScreen > @PerActivity
@Singleton: Application wide
@PerScreen: Multiple activty lifecycles, keep alive during config changes
@PerActivity: Maybe Context dependent, recreate with every activity
当发生配置更改时,您现在可以丢弃所有@PerActivity对象并重新创建它们,同时保留对@PerScreen对象的引用.
您可能会注意到我如何继续讨论保留@PerScreen组件,而不是保留演示者,这是重要的部分:
在@PerScreen作用域组件上,调用
myPerScreenComponent.getMyPresenter()
将始终返回相同的@PerScreen作用域演示者.
现在,如果您的@PerActivty范围组件是MyPerScreenComponent的子组件,则注入您的活动将始终为您提供相同的@PerScreen范围的演示者,该演示者将在方向更改后继续存在.
为了防止内存泄漏,@ Perbercreen范围内的任何对象都不能引用Activity,并且演示者只应在其视图上保留WeakReference(或者你必须确保在destroy上将视图设置为null).
这就是范围的目的,这就是你如何避免在视图重新创建时创建额外的主持人对象.
因此,您应该尝试将组件保留在加载程序中,以避免不必要地重新创建对象,而不是将您的演示者保留在加载程序中.
所有这些都可能会引入更多复杂性,因为您现在每个活动有2个范围和更多回调.
我还看到了其他方法,您可以在演示文稿中将演示者作为单身人士,但这会引入相同的问题,您必须确保不要保留对您的活动的任何引用.
就个人而言,我只是重新创建演示者并恢复状态,但如果您选择使用您的方法,则应确保您对范围和依赖关系有充分的了解.
内容总结
以上是互联网集市为您收集整理的java – 带有MVP的Dagger 2,避免在视图重新创建时创建额外的presenter对象全部内容,希望文章能够帮你解决java – 带有MVP的Dagger 2,避免在视图重新创建时创建额外的presenter对象所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。