Android MVP模式中释放Presenter的正确方式

4
我正在使用MVP架构,现在遇到了如何正确释放presenter的问题。首先,让我告诉大家发生了什么。
问题:
1)我的presenter发出一个异步服务器请求。
2)当我接收到服务器响应时,我的视图(fragment)已经分离,但我仍然保留着它的实例,这可能会导致内存泄漏,并且我还调用了来自View的方法来设置从服务器接收的一些数据。
3)在我的视图中,我使用从“getActivity()”方法获取的上下文,在此阶段将返回null。
我尝试解决这个问题的方式:
1)当我分离Fragment时,我在presenter上调用“release()”方法。在这种方法中,我考虑将我的view实例设置为null。这样做是可行的,但我需要在我的presenter中添加null检查,以检查我的视图是否已经设置为null。这似乎不是最好的方法。
2)在我的视图(fragment)中,在使用之前检查“getActivity()”是否为null。但这并不能解决内存泄漏问题,并且我需要在我的所有片段中添加此检查;
你们有其他的建议吗?有没有一种适当的方法来释放我的presenter,使得每当我的presenter调用我的视图上的方法时,我都可以确信视图已连接到活动中?EventBus是否是一种好的解决方案?
非常感谢!
1个回答

3
主持人层的主要目标之一是与Android Framework无关,这意味着您不需要导入任何来自Android Framework的包,使其成为纯Java类。您应该使您的ActivityFragment实现ActivityView接口或FragmentView接口,并让具体的ActivityFragment实现该接口。现在,在onCreate()中创建一个Presenter实例,并将View(Activtity或Fragment)作为参数传递,并且在Presenter类中,您将拥有ActivityViewFragmentView引用,通过构造函数进行初始化,就像这样:

Activity.java

public class Activity implements ActivityView {
    ...
    private Presenter mPresenter;

    public void onCreate() {
         // some other code

         mPresenter = new Presenter(this);

         // some other code
    }

Presenter.java

    public class Presenter {
         private ActivityView mActivityView;


         public Presenter(ActivityView activityView) {
           this.mActivityView = activityView;
         }
}

现在,您可以调用ActivityFragments中的方法,但这些方法必须在接口中列出。如果您使用RxJava2,则可以在Presenter中拥有CompositeDisposable对象,并将网络调用添加到该可处理对象中,在来自ActivityFragment的适当生命周期方法中,您可以通过Presenter调用compositeDisposable上的dispose()方法。以这种方式,您将清除任何正在进行的网络操作,使其不会更新UI(如果UI不存在)。希望这个答案能够帮助您 :)

嗨@RadoVidjen,感谢您的回复! 是的,我正在按照您所说的做。我将Presenter完全独立于Android组件,并且所有Presenter和View之间的通信都是使用接口完成的。当我说我从Presenter调用视图方法时,我的意思是我的Presenter调用了在我的视图接口上列出的方法。我正在考虑避免使用RxJava,因为我想在以后实现LiveData,这样RxJava就有点无用了(根据我的理解,我对RxJava的了解还很有限)。我是正确的吗?您是否有其他建议不使用RxJava? - John Santos
你确定你的内存泄漏了吗?因为如果使用接口进行通信,那么我认为这是松耦合的,这意味着如果View消失了,presenter也将变为null...也许我错了,但你可以用LeakCanary测试一下。关于RxJava,我认为你可以将其与LiveData结合起来,只需要稍微研究一下,看看这两者如何协同工作。无论如何,如果你使用Retrofit进行网络操作,应该添加RxJava2适配器,因为这会使异步任务更容易,并将响应传递给主线程。 - RadoVidjen
是的,我认为我需要看一下 RxJava。非常感谢。 - John Santos
肯定会有泄漏,因为您正在持有ActivityView,而它实际上是一个Activity对象(因为您的Activity已经实现了该接口),最好的方法是在调用视图方法之前进行null检查,我想这是相当标准的。 - Ankit Dubey
我真的无法不用代码来表达,如果您能提供源代码那就太好了。 - RadoVidjen
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接