Specific cases - mandriana/android-mvp-core GitHub Wiki

Here you will find a way to deal with specific cases.

I need a context in my presenter

Despite the fact you should avoid it, your presenter may need an access to a context. The easiest way to do it, is using dependency injection in your presenter class.

If you do no want to hold a context reference in your presenter, you can do it this way :

  1. Create a view interface to access the context :
public interface ContextView {
    Context getCurrentContext();
}
  1. Make your custom view interface extends the ContextView :
public interface MainView extends ContextView {
    void onTaskCompleted();
    void onTaskFailed();
}
  1. Implement the view :
public class MainActivity extends BasePresenterActivity<MainPresenter> 
    implements MainView {

    @NonNull
    @Override
    protected MainPresenter instantiatePresenter() {
        return new MainPresenter();
    }

    @Override
    public Context getCurrentContext(){
        return this;
    }

    // ... Make a call to getPresenter().doTask()
}
  1. Access the context in the presenter
public class MainPresenter extends RxPresenter<MainView> {

    public static final String TASK = "myTask";

    public void doTask(){
        MainView view = getView();

        if(view != null){

            // You can access the context
            String s = view.getCurrentContext().getResources().getString(R.string.sample);

            start(TASK, Observable.just(s), 
                null,
                new OnError<MainView>() {
                    @Override
                    public void call(@NonNull MainView mainView, @NonNull Throwable throwable) {
                        mainView.onTaskFailed();
                    }
                },
                new OnCompleted<MainView>() {
                    @Override
                    public void call(@NonNull MainView mainView) {
                        mainView.onTaskCompleted();
                    }
                });
        }
    }
}

StartOnViewAttached

This is a specific method to defer a task when the view is attached.

Let's take the case you ask for permissions. When permission is granted, in onRequestPermissionsResult you want to perform a task, copying a file for instance.

You may call getPresenter().copyFiles() but your file manager needs a context. Access to context can be resolved using the previous section. But there is one caveat : in the presenter getView() is not null only when the view is attached, it means after onResume() and onRequestPermissionsResult is called before onResume().

To resolve this problem, you can use the startOnViewAttached which will put the task on a queue until the view is attached again :

// A tag is necessary and should be the same in the method copyFiles()
getPresenter().startOnViewAttached(MainPresenter.TASK_COPY_FILES, new Action1<MainView>() {
    @Override
    public void call(MainView mainView) {
        getPresenter().copyFiles();
    }
});

When getPresenter().copyFiles() the view will be attached and you will be able to access the context.

⚠️ **GitHub.com Fallback** ⚠️