Specific cases - mandriana/android-mvp-core GitHub Wiki
Here you will find a way to deal with specific cases.
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 :
- Create a view interface to access the context :
public interface ContextView {
Context getCurrentContext();
}
- Make your custom view interface extends the ContextView :
public interface MainView extends ContextView {
void onTaskCompleted();
void onTaskFailed();
}
- 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()
}
- 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();
}
});
}
}
}
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.