In my app I work with ContentProvider
and use LoaderManager.LoaderCallbacks<Cursor>.
Fragment (View)
public class ArticleCatalogFragment extends BaseFragment
implements ArticleCatalogPresenter.View,
LoaderManager.LoaderCallbacks<Cursor> {
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return onCreateArticleCatalogLoader(args);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
data.registerContentObserver(new LoaderContentObserver(new Handler(), loader));
updateUI(data);
}
private Loader onCreateArticleCatalogLoader(Bundle args) {
int categoryId = args.getInt(CATEGORY_ID);
Loader loader = new ArticleCatalogLoader(this.getActivity(), categoryId);
return loader;
}
}
From point of view MVP I need:
Presenter
public class ArticleCatalogPresenter extends BasePresenter
implements LoaderManager.LoaderCallbacks<Cursor> {
View view;
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return onCreateArticleCatalogLoader(args);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
data.registerContentObserver(new LoaderContentObserver(new Handler(), loader));
view.updateUI(data);
}
private Loader onCreateArticleCatalogLoader(Bundle args) {
int categoryId = args.getInt(CATEGORY_ID);
Loader loader = new ArticleCatalogLoader(context, categoryId); // need Context
return loader;
}
interface View {
updateUI(Cursor data)
}
}
So, I need a context in Presenter.
There are some nuances:
Presenter know about the Context - it is bad, Presenter should not know about the Android.
Having a Context in Presenter can lead to memory leak.
I am now worried about how to avoid problems such as memory leaks, and how best pass Context in Presenter, use Application Context or Activity/Fragment?
I would strongly suggest that the presenter should have no concept of the Android Context (or any other Android classes). By completely separating your Presenter code from the Android system code you are able to test it on the JVM without the complication of mocking system components.
What is MVP? The MVP pattern allows separating the presentation layer from the logic so that everything about how the UI works is agnostic from how we represent it on screen. Ideally, the MVP pattern would achieve that the same logic might have completely different and interchangeable views.
MVP (Model — View — Presenter) comes into the picture as an alternative to the traditional MVC (Model — View — Controller) architecture pattern. Using MVC as the software architecture, developers end up with the following difficulties: Most of the core business logic resides in Controller.
A Presenter is used to generate View s and bind Objects to them on demand. It is closely related to the concept of an RecyclerView. Adapter , but is not position-based. The leanback framework implements the adapter concept using ObjectAdapter which refers to a Presenter (or PresenterSelector ) instance.
Adding context to Presenter is not good since, the presenter is responsible for business logic. To deal with context, you need to have the Fragment/Activities make use of Callbacks with the help of interfaces which will state what actions need to be perform by the activity/fragment when dealing with views. Fragment / Activities are responsible to provide Context.
Example:
interface BaseContract {
interface BaseView {
//Methods for View
void onDoSomething();
}
interface BasePresenter {
void doSomething();
}
}
class BaseMainPresenter implements BaseContract.BasePresenter {
BaseContract.BaseView view;
BaseMainPresenter(BaseContract.BaseView view) {
this.view = view;
}
@Override
public void doSomething() {
if (view != null)
view.onDoSomething();
}
}
class DemoClass implements BaseContract.BaseView {
//Create object of Presenter
/****
* Example :
* BaseMainPresenter baseMainPresenter = new BaseMainPresenter(this);
*/
@Override
public void onDoSomething() {
//Deal with Context here.
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With