现在大家写项目都流行MVP模式,网上也有很多大神写的Demo,本人也有尝试着去写,发现MVP思想确实很好!不过发现官方版的MVP虽然好用,却也产生了很多类,理解也不是那么好理解。因此,自己根据MVP实现了简易的方式来达到数据请求和Activity分离,适用于中小型项目。
先看下整体目录
就是如此简洁和易懂,下面具体分析下一些类的主要用法
BasePresenter类主要有三个方法,attachView用于绑定View,在Activity实例化Presenter后,需要绑定View;detachView解绑,Activity销毁或调用该方法
public class BasePresenter<T extends MvpView> implements Presenter<T> {
protected T mMvpView;
LinkedHashMap<String, Object> map;
@Override
public void attachView(T mvpView) {
mMvpView = mvpView;
}
@Override
public void detachView() {
mMvpView = null;
}
public boolean isViewAttached() {
return mMvpView != null;
}
public T getMvpView() {
return mMvpView;
}
public void checkViewAttached() {
if (!isViewAttached()) throw new MvpViewNotAttachedException();
}
public static class MvpViewNotAttachedException extends RuntimeException {
public MvpViewNotAttachedException() {
super("Please call Presenter.attachView(MvpView) before" +
" requesting data to the Presenter");
}
}
}
Preseter接口提供attchView和deatchView两个方法
public interface Presenter<V extends MvpView> {
void attachView(V mvpView);
void detachView();
}
MvpView提供两个公共方法,实现该接口都必须实现这两个方法
public interface MvpView {
void onSuccess(String message);
void onFail(String message);
}
Demo
本例通过请求gank的API的历史数据(http://gank.io/api)只需三个步骤就能获取数据并设置给Activity
View
定义接口用于请求成功后需要返回给Activity的数据
public interface HistoryView extends MvpView {
//获取历史数据
void getHistories(List<HistoryEntity> entities);
}
Presenter
用户请求并处理数据,处理完只需将Activity需要的数据返回
public class HistoryPresenter extends BasePresenter<HistoryView> {
private Context context;
public HistoryPresenter(Context context){
this.context=context;
}
public void getHistory(int total,int page){
HttpUtil.get(Constants.METHOD_HISTORY_CONTENT+total+"/"+page, new HttpCallBack() {
@Override
public void onResponse(JSONObject jsonObject) {
try {
//解析数组
JSONArray jsonArray=jsonObject.getJSONArray("results");
Type listType = new TypeToken<List<HistoryEntity>>() {
}.getType();
List<HistoryEntity> entities = new Gson().fromJson(String.valueOf(jsonArray), listType);
getMvpView().getHistories(entities);
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onErrorResponse(int recode, String message) {
getMvpView().onFail(message);
}
});
}
}
Activity
实现view接口并初始化presenter
public class MainActivity extends AppCompatActivity implements HistoryView {
private HistoryPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//showDialog()
//实例化
presenter=new HistoryPresenter(this);
//绑定view,否则会报空指针异常
presenter.attachView(this);
presenter.getHistory(10, 1);
}
@Override
public void onSuccess(String message) {
//dismissDialog()
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void onFail(String message) {
//dismissDialog()
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void getHistories(List<HistoryEntity> entities) {
//dismissDialog()
for (HistoryEntity entity : entities) {
Log.e("history", entity.toString());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView();
}
}
这样就简单的实现数据和Activity的分离,Activity代码就非常简洁了,整个项目也不难理解
如需源代码到github自行下载EasyMVP(https://github.com/liuger/EasyMVP)