androiddesign-patternsmodelmvppresenter

Android MVP How to get data back from model to presenter


After some time developing personal Android Applications I found that usually Activities get really big and have both logic and UI operations quite mixed up.

So looking for a way to separate logic from UI I came across MVP pattern and now I'm trying to implement it in the application I'm going to develop.

So basically this would be my approach:

enter image description here

The issue I'm facing now is that in order to get data back from model to presenter I'd do something like this:

public static ModelManager (OnePresenter presenter)
{
    localPresenter = presenter
}

And then:

public onReturnData(){
    localPresenter.returnData();
}

The issue is that Model Manager could be called from any presenter at any time so how could I pass a reference of a Generic Presenter?

Thanks a lot.


Solution

  • To be honest, I do not think that your approach is the best way to handle this. You can actually just use an observer pattern or an EventBus to notify the presenters when the data was received. That way you can keep your presenter separated from the model .. this should make the whole architecture a little cleaner.

    But to answer your question:

    All of your separate items should not communicate directly with one another. Instead the real implementation should be hidden behind an interface. That means, the view does not know anything about the presenter (it doesn’t even know that a presenter class exists), it only knows the interface the exposes the calls that the view needs.

    That way you can simply define an interface for the communication between the ModelManager and the presenter:

    interface ModelToPresenterInterface {
        void returnData(Object data);
    }
    

    All your presenters need to implement this (of course):

    public myPresenter implements ModelToPresenterInterface {
        void returnData(Object data){
            // put your business logic here
        }
    }
    

    With this, you can just pass the interface (which every one of your presenters has implemented) to the ModelManager. This should probably not happen in the constructor, since there will only be a single instance of your manager that is used by every presenter.

    static class ModelManager{
    
        List<ModelToPresenterInterface> callbackList = new ArrayList<>();
    
        void addListeningPresenter(ModelToPresenterInterface presenter){
            callbackList.push(presenter);
        }
    
        public onReturnData(Object data){
            for (int i = 0;i<callbackList.size();++i){
                callbackList.get(i).returnData(object);
            }
        }
    }
    

    As long as you are sure that there is always only a single presenter that is interested in your data (so that there are no presenters further down the stack) then you can also just use a single variable that gets overwritten for each new presenter.

    Also be very carefull that you do remove the presenters from the list when it gets destroyed! (if not this will create major memory leaks)

    Once again: I really think you will get better results using an EventBus or something similar, but this version should also work. Hope I could help and let me know if you have additional questions :)