MVP
MVP(Model-View-Presenter)是 MVC 的演化版本,会将业务逻辑和视图逻辑抽象到接口中。MVP 的角色定义如下:
- Model:负责数据的管理。主要提供数据的存取能力。Presenter 需要通过 Model 层来存储、获取数据。
- View:负责UI的显示。处理用户事件和视图部分的展示。在 Android 中,它可能是 Activity、Fragment 类或者是某个 View 控件。
- Persenter:负责逻辑控制。作为 View 和 Model 之间沟通的桥梁。
View层产生事件,通知Persenter层,Persenter层则通知Model层更新数据,
Model层更新数据后,返回并通知Persenter层,Persenter层再通知View层更新界面。
优点;完全解耦View层和Model层。Model,View,Presenter各司其职,职责更清晰。甚至可由多人分工合作完成。(当然,灵活修改,适合自己的项目才最好,比如有时Model层的业务逻辑也可以放在Presenter层,从而取消Model层)
缺点;时间上来讲导致开发效率低下,因为需要借助接口回调的方式转发消息,从而导致接口类文件增多(Model,View,Presenter都需要各自的接口,再加上他们各自的实现,也就是说每一个页面都会有6个java文件,而每一个类的加载又会消耗资源),且实现类无法避免许多无用的空实现。(当然,可通过泛型参数、抽象父类的方式,将一些公用的Model及Presenter抽象出来)当然还有一个问题,MVP 个人实现差异比较大。
示例
同时,结合 RxJava 和 Retrofit 来做网络请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Contract {
public interface ContractModel{ void getDataList(String id,String type ,BaseCallbackListener<UserBean> callbackListener); }
public interface ContractView{ void showView(UserBean user); }
public interface ContractPresenter extends BasePresenter { void startRequestData(String id,String type); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class ModelIml implements Contract.ContractModel{
@Override public void getDataList(String id,String type, final BaseCallbackListener<UserBean> callBack) { RetrofitUtils.newInstence() .create(Info.class) .getDataList(id) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<UserBean>() { @Override public void onSubscribe(Disposable d) { callBack.onStart(); }
@Override public void onNext(UserBean user) { if ("200".equals(user.getCode())) { callBack.onNext(user); }else { callBack.onError(user.getMsg()); } }
@Override public void onError(Throwable e) { Log.e("TAG",e.getMessage()); e.printStackTrace(); if (e instanceof HttpException) { HttpException httpException = (HttpException) e; int code = httpException.code(); if (code == 500 || code == 404) { callBack.onError("服务器出错"); } }else if (e instanceof ConnectException) { callBack.onError("网络断开,请打开网络!"); } else if (e instanceof SocketTimeoutException) { callBack.onError("网络连接超时!!"); } else { callBack.onError("发生未知错误" + e.getMessage()); } }
@Override public void onComplete() {
} });
} }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| public class MainActivity extends BaseMvpActivity implements Contract.ContractView {
private Contract.ContractPresenter presenter = new PresenterIml(this);
@Override public int getLayoutResId() { return R.layout.activity_main; }
@Override public void initView() {
}
@Override public void initData() { }
@Override protected BasePresenter bindPresenter() { return presenter; } @Override protected void onResume() { super.onResume(); if (presenter!=null) presenter.startRequestData("","type"); }
@Override public void showView(UserBean user) { Log.e("TAG",user.toString()); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public abstract class BaseMvpActivity extends BaseActivity { private BasePresenter presenter = null; public Context mContext;
@Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); presenter = bindPresenter(); mContext = this; }
protected abstract BasePresenter bindPresenter();
@Override public void onDestroy() { super.onDestroy(); if (presenter != null) { presenter.onDestroy(); presenter = null; System.gc(); } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| public class PresenterIml implements Contract.ContractPresenter { private Contract.ContractView contractView; private Contract.ContractModel contractModel;
public PresenterIml(Contract.ContractView contractView) { this.contractView = contractView; contractModel =new ModelIml(); }
@Override public void onDestroy() { contractView = null; System.gc(); }
@Override public void startRequestData(String id, final String type) { contractModel.getDataList(id,type, new BaseCallbackListener<UserBean>() { @Override public void onStart() { if (contractView == null) { return; } }
@Override public void onNext(UserBean result) { if (contractView == null) { return; } switch (result.getCode()) { case "200": contractView.showView(result); break; case "500":
break; default: break; } }
@Override public void onError(String str) { if (contractView == null) { return; } } }); } }
|
一种方法,自动实现 String 和集合的非空判断。
Generate–>Getter and Setter–>Getter template–> ··· –> + –>添加如下代码;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| #if($field.modifierStatic) static ## #end $field.type ## #set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project)))) #if ($field.boolean && $field.primitive) #if ($StringUtil.startsWithIgnoreCase($name, 'is')) #set($name = $StringUtil.decapitalize($name)) #else is## #end #else get## #end ${name}() { #if ($field.string) return $field.name == null ? "" : $field.name; #else #if ($field.list) if ($field.name == null) { return new ArrayList<>(); } return $field.name; #else return $field.name; #end #end }
public String getName() { return name == null ? "" : name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public List<String> getmList() { if (mList == null) { return new ArrayList<>(); } return mList; }
public void setmList(List<String> mList) { this.mList = mList; }
|
备注
参考资料:
《Android Jetpack开发 原理解析与应用实战》
Android 进阶之光
传送门:GitHub