Android MVP open Activity from Presenter, anti-pattern?

Jose M Lechon picture Jose M Lechon · Apr 28, 2016 · Viewed 11.8k times · Source

Would it be an anti-pattern if from a Presenter layer I open an Activity?

If so, should I manage the navigation of the app from the View Layer?

Answer

Saeed Masoumi picture Saeed Masoumi · Apr 28, 2016

Yes it's an anti-mvp-pattern. Based on passive view in MVP, you lost your testability, because you don't have to deal with the android framework in your presenter.

So it's better to manage the navigation of the app from the View Layer.

class MyPresenter {
    MyPresenter.View view;

    void backButtonClicked() {
        view.navigateToHomeScreen();
    }

    public interface View {
        void navigateToHomeScreen();
    }
}

class MyActivity extends Activity implements MyPresenter.View {
    @Override
    void navigateToHomeScreen() {
        startActivity(...)
    }

    @OnClick(R.id.my_button)
    void onClick() {
        presenter.backButtonClicked();
    }
} 

Also another advantage of this way is that it will be easy to replace activity with a fragment or a view.

Edit 1:

Morgwai said this way will break separation of concern and single responsibility, but you cannot have single responsibility every where. Sometime you need to violate it. Here is an example from Google for MVP:

TaskDetailPresenter calls ShowEditTask which is responsible to open a new Activity inside TaskDetailFragment.

But also you can use CommandPattern which is a better approach

interface NavigationCommand {
    void navigate();
}

So, Presenter will use it when it needs.