GCX-HCI/ThirtyInch

Initializing presenter state from intent

Closed this issue · 4 comments

If I receive an intent in my activity that should initialize it's state, how do I pass this to my presenter? Shouldn't onCreate in the presenter receive this intent? Or maybe there's a better way?

By the way, thanks for the great library, I've found it the best one I've tried (out of a whole bunch..).

It is a good practice in the MVP pattern to leave the Presenter plain old Java as much as possible. It makes it much easier to test the presenter without the need of Android Tests or Robolectric for example.

If you just want to initialize the presenter with the data, you could read the intent by getIntent() in the providePresenter() of the Activity and pass the data into the Presenter's Constructor.
If you want to "update" the presenter data by Intent data, provide a method in the presenter for it and call it with the data e.g. in onCreate().

This is from the sample project:

    @NonNull
    @Override
    public AddEditTaskPresenter providePresenter() {
        final String taskId = getIntent()
                .getStringExtra(AddEditTaskActivity.ARGUMENT_EDIT_TASK_ID);
        final TasksRepository tasksRepository = Injection
                .provideTasksRepository(getApplicationContext());

        return new AddEditTaskPresenter(taskId, tasksRepository);
    }

Thank you, that is a good idea, but since I'm using dagger2 for presenter dependencies, I had to use:

@Inject Provider<MyPresenter> presenterFactory

then I used the graph to inject it in providePresenter method. The dependecies are passed by injecting the presenter's constructor for ease of testing. So in the end I had to make a setter method on the presenter to set the state on the activity's onCreate. Am I doing this right? I thought it was wrong for the activity to do any actions, it should only be a 'passive' view displayer?

Thanks for all your answers!

I never use dagger to inject the presenter. I don't think it's useful. You never exchange the presenter with a mock implementation when doing tests. So my Activities and Presenters are hardcoded glued together.
On the other hand using Dagger to inject dependnecies inside you presenter could be useful. If you're starting a new project consider building your app with constructor injection instead of dagger. It's often easier and has a good separation; inject android dependencies in your Activity and mock dependencies in your tests.

On android the passive view is often not possible. It is possible for your view implementation but the Activity has functionality which goes beyond the functionality of a view. Initialising the presenter, starting other Activities and handle the ActivityResult are things which aren't view related. But there is no other way to do it on Android 😞.

Don't over engineer and get things done in a testable way where it is testable, that's probably my best tip ✌️