简体   繁体   中英

Android MVP Proper Way to Release Presenter

I am working with MVP architecture and I'm stuck on how to proper release the presenter. First, let me tell you guys what is happening.

PROBLEM

1) My presenter make an async server request.

2) When I receive the server response, my view (fragment) was already detached but I still have its instance hold on my presenter (which can causes memory leaks) and I call a method from View to set some data I received from the server.

3) Inside my view I use the context from getActivity() method, which in this stage will return null .

HOW I TRIED TO FIX THIS PROBLEM

1) When I detach the fragment I call a release() method on my presenter. Inside this method I thought about setting the instance of my view to null. This would work but then I would need to add null checks literally everywhere in my presenter checking whether my view was already set to null or not. Doesn't seems to be the best approach.

2) In my view (fragment), check whether getActivity() is null before using it. But it doesn't fix the memory leak problem and I would need to add this check literally everywhere in my Fragment(s);


Do you guys have an alternative for that? Is that a proper way to release my presenter when my fragment is detached in a way that whenever my presenter call a method on my view I will be sure that view is attached to an Activity? Is EventBus a good approach for that?

Thanks a lot!

The one of the main goals of the presenter layer is to be Android Framework independent, that means that you don't have in imports any of the packages from Android Framework, making it pure Java class. You should make your Activity or Fragment implements the ActivityView interface or FragmentView interface, ant let concrete Activity or Fragment implement that interface. Now, in the onCreate() you create an instance of the presenter and pass as an argument the View (Activtity or Fragment), and in Presenter class you will have ActivityView or FragmentView reference, initializing it through the constructor, something like this:

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;
         }
}

Now you can call the methods in the Activity or Fragments , but those methods must be listed in the interface. In case your are your RxJava2, you can have CompositeDisposable object in the Presenter , adding your network calls to that disposable, and in proper lifecycle methods from Activity or Fragment , your can call dispose() method on compositeDisposable , through Presenter of course. In that way you will clean any ongoing network operations, making it not update the UI if the UI is not present. Hope this answer helps you :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM