MVP框架担任角色
Model: 处理数据,包过网络请求、提交数据;缓存、读写本地数据、写入;写入、读取数据库数据等
View: 提供Activity需要实现方法,本身是一个接口,实际在Presenter中被调用执行。
Presenter: 业务处理,内部持有Model和View;使用CallBack获取Model获取结果信息。
Activity: 实现View提供方法,持有Presenter对象;在监听事件中调用Presenter方法,其他初始化与之前MVC一样。
使用优缺点
优点:
1、解耦:对于页面处理差异性、兼容性非常好;在于请求数据参数可能需要改变情况可以很好做到隔离性,在Model可以处理,不需要改变Activity流程。
2、分解:简化代码、将一个类中几百上千行都拆分处理,使得整个流程看起来更清晰。
缺点:
1、建立类多、容易造成内存泄漏,对于不熟悉Mvp上手有点难度、不好调试出现bug,不清楚执行方法流向。
总结:在对于单一功能、逻辑不复杂的页面并不建议使用MVP模式分解;所以最后看项目适用情况,哪个页面需要MVP分解,大多页面使用MVC即可。
实例
Demo结构
解耦
需求:对于不同地区app登录检车业务、其中各个地区以内网开发;登录参数可能由于不同地区有细微差异性。登录页面需要高度统一不变的前提下,使用MVP就是量身打造。
IView 接口
public interface IView {
void show();
void hide();
void toMainActivity();
void tip(String msg);
}
这个接口主要负责对于Activity一些形态,比如提示信息,显示进度条,调转其他页面等
LoginActivity 页面
public class LoginActivity extends AppCompatActivity implements IView,View.OnClickListener{
private IPresenter presenter;
private ProgressDialog progressDialog;
private EditText et_name;
private EditText et_password;
private Button btn;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et_name=findViewById(R.id.username);
et_password=findViewById(R.id.password);
btn=findViewById(R.id.btn);
btn.setOnClickListener(this);
presenter=new IPresenter(this,new IMode());
progressDialog=new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("正在请求...");
}
@Override
public void show() {
progressDialog.show();
}
@Override
public void hide() {
progressDialog.hide();
}
@Override
public void toMainActivity() {
startActivity(new Intent(this, HomeActivity.class));
}
@Override
public void tip(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn:
String name=et_name.getText().toString().trim();
String password=et_password.getText().toString().trim();
presenter.login(name,password);
break;
default:
break;
}
}
}
这个页面LoginActivit对于初始化控件及点击事件、获取控件数据操作依旧保留不变,对于实现view方法具体由Presenter调用。
IMode 处理数据
public class IMode {
/**
* 登录接口
* @param url
* @param map
* @param callback
*/
public void login(String url, Map map , StringCallback callback){
OkHttpManager.get(url,map).execute(callback);
}
/**
* 获取当前站点接口
*/
public void getNowWhere(String url,StringCallback callback){
OkHttpManager.get(url).execute(callback);
}
}
这个Imode处理数据,请求网络,结果StringCallBack回调,并且将结果返回到Presenter处理。上面使用的是鸿洋大神OKhttpUtils框架。
IPresenter 业务处理
public class IPresenter {
private IView view;
private IMode mode;
public IPresenter(IView view,IMode mode){
this.view=view;
this.mode=mode;
}
public void login(final String name, final String psw){
if(TextUtils.isEmpty(name)){
if(isViewAttached()){
view.tip("用戶名為空!");
}
return;
}
if(TextUtils.isEmpty(psw)){
if(isViewAttached()){
view.tip("密碼為空!");
}
return;
}
if(isViewAttached()){
view.show();
}
//延迟一秒,请求数据;显示进度条作用
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mode.getNowWhere(NetUrl.KEY_WHERE, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if(isViewAttached()){
view.hide();
view.tip("获取站点信息错误:"+e.getMessage());
}
}
@Override
public void onResponse(String response, int id) {
if(isViewAttached()){
view.hide();
}
String[] where={"A","B","C","D"};
int index=new Random().nextInt(4);
String now=where[index];
Log.e("QISHUI","当前登录站:"+now);
switch (now){
case "A":
loginA(name,psw);
break;
case "B":
loginB(name,psw);
break;
case "C":
loginC(name,psw);
break;
case "D":
loginD(name,psw);
break;
default:
break;
}
}
});
}
},1000);
}
/**
* A站点登录
*/
public void loginA(String name ,String password){
if(isViewAttached()){
view.show();
}
Map<String,String> map=new HashMap();
map.put("namea",name);
map.put("pwda",password);
mode.login(NetUrl.KEY_WHERENOW, map, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if(isViewAttached()){
view.hide();
view.tip("登录A信息错误:"+e.getMessage());
}
}
@Override
public void onResponse(String response, int id) {
if(isViewAttached()){
view.hide();
view.toMainActivity();
//其他处理
}
}
});
}
/**
* B站点登录
*/
public void loginB(String name ,String password){
if(isViewAttached()){
view.show();
}
Map<String,String> map=new HashMap();
map.put("nameb",name);
map.put("pwdb",password);
map.put("mac","1s:12:34:67:rt:13");
mode.login(NetUrl.KEY_WHERENOW, map, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if(isViewAttached()){
view.hide();
view.tip("登录B信息错误:"+e.getMessage());
}
}
@Override
public void onResponse(String response, int id) {
if(isViewAttached()){
view.hide();
view.toMainActivity();
//其他处理
}
}
});
}
/**
* C站点登录
*/
public void loginC(String name ,String password){
if(isViewAttached()){
view.show();
}
Map<String,String> map=new HashMap();
map.put("namec",name);
map.put("pwdc",password);
map.put("imei","123456789044444");
mode.login(NetUrl.KEY_WHERENOW, map, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if(isViewAttached()){
view.hide();
view.tip("登录C信息错误:"+e.getMessage());
}
}
@Override
public void onResponse(String response, int id) {
if(isViewAttached()){
view.hide();
view.toMainActivity();
//其他处理
}
}
});
}
/**
* D站点登录
*/
public void loginD(String name ,String password){
if(isViewAttached()){
view.show();
}
Map<String,String> map=new HashMap();
map.put("named",name);
map.put("pwdd",password);
map.put("imei","123456789044444");
map.put("mac","1s:12:34:67:rt:13");
mode.login(NetUrl.KEY_WHERENOW, map, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if(isViewAttached()){
view.hide();
view.tip("登录D信息错误:"+e.getMessage());
}
}
@Override
public void onResponse(String response, int id) {
if(isViewAttached()){
view.hide();
view.toMainActivity();
//其他处理
}
}
});
}
public void attachView(IView v) {this.view= v;}
public void detachView() {
this.view= null;
}
public boolean isViewAttached(){
return view!= null;
}
}
MVP中主要角色,将Actiivty中View方法调用,同时处理IMode数据
其他
NetUrl.class
public class NetUrl {
public static final String KEY_WHERE = "https://www.baidu.com";
public static final String KEY_WHERENOW = "https://www.baidu.com";
}
保存API地址
OkHttpManager.class
public class OkHttpManager {
// get 异步请求
public static RequestCall get(String url, Map<String, String> params) {
printLog(url,params);
return OkHttpUtils.get().url(url).params(params).build();
}
// get 异步请求
public static RequestCall get(String url) {
printLog(url,null);
return OkHttpUtils.get().url(url).build();
}
//post请求 异步请求
public static RequestCall post(String url, Map<String, String> params) {
printLog(url,params);
return OkHttpUtils.post().url(url).params(params).build();
}
//post请求 异步请求
public static RequestCall post(String url) {
printLog(url,null);
return OkHttpUtils.post().url(url).build();
}
//post一个json类型数据
public static RequestCall postJson(String url, String jsonData) {
printLog(url,jsonData);
return OkHttpUtils.postString().url(url).content(jsonData).mediaType(MediaType.parse("application/json; charset=utf-8")).build();
}
// post一个文件
public static RequestCall postFile(String url, File file) {
printLog(url,file.getAbsolutePath());
return OkHttpUtils.postFile().url(url).file(file).build();
}
// 下载文件
public static void downloadFile(String url, String path, String name) {
printLog(url,path);
get(url).execute(new FileCallBack(path, name)
{
@Override
public void onAfter(int id) {
super.onAfter(id);
}
@Override
public void onError(Call call, Exception e, int id) {
}
@Override
public void onResponse(File response, int id) {
}
@Override
public void inProgress(float progress, long total, int id) {
}
});
}
//取消请求
public static void cancel(String url) {
OkHttpUtils.get().url(url).build().cancel();
}
/**
* 打印路径信息
*
* @param url
*/
private static void printLog(String url,Object obj) {
StringBuilder sb = new StringBuilder();
sb.append(url).append("?");
if(obj instanceof Map){
Map<String, String> params= (Map<String, String>) obj;
if (params != null) {
for (String s : params.keySet()) {
sb.append(s).append("=").append(params.get(s)).append("&");
}
}
}else {
if (obj!=null){
sb.append(obj);
}
}
Log.e("QISHUI",sb.toString());
}
}
简易处理网络请求
activity_main
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="用户名"/>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="密码"/>
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登录"/>
</LinearLayout>
至于HomeActivity就是新建一个页面,没有任何其他逻辑。
运行输出
06-29 11:18:35.244 8518-8518/com.vkeline.mvpdemo E/QISHUI: https://www.baidu.com?
06-29 11:18:35.379 8518-8518/com.vkeline.mvpdemo E/QISHUI: 当前登录站:A
06-29 11:18:35.379 8518-8518/com.vkeline.mvpdemo E/QISHUI: https://www.baidu.com?pwda=cgg&namea=qwe&
06-29 11:18:39.001 8518-8518/com.vkeline.mvpdemo E/QISHUI: https://www.baidu.com?
06-29 11:18:39.053 8518-8518/com.vkeline.mvpdemo E/QISHUI: 当前登录站:C
06-29 11:18:39.053 8518-8518/com.vkeline.mvpdemo E/QISHUI: https://www.baidu.com?imei=123456789044444&pwdc=cgg&namec=qwe&
06-29 11:18:42.960 8518-8518/com.vkeline.mvpdemo E/QISHUI: https://www.baidu.com?
分解
需求:录入几十条数据,并对数据验证,缓存,清理已填数据等,这种类型适合使用MVP细化分解。
ISubmitModel.class 提交数据
public class ISubmitModel {
/**
* 提交数据
* @param url
* @param map
* @param callback
*/
public void submit(String url , Map map, StringCallback callback){
OkHttpManager.get(url,map).execute(callback);
}
}
ISubmitView.class 业务接口、功能点
public interface ISubmitView {
void initSet();
void tip(String message);
void save();
}
ISubmitPresenter 业务处理
public class ISubmitPresenter {
private ISubmitModel model;
private ISubmitView view;
public ISubmitPresenter(ISubmitView view, ISubmitModel model) {
this.view = view;
this.model = model;
}
public void submit(SubmitBean submitBean) {
if (!check(submitBean)) {
return;
}
Map map = new HashMap();
map.put("sbstring", new Gson().toJson(submitBean));
model.submit(NetUrl.KEY_SUBMIT, map, new StringCallback() {
@Override
public void onError(Call call, Exception e, int id) {
if (isViewAttached()) {
view.tip("提交失败");
}
}
@Override
public void onResponse(String response, int id) {
if (isViewAttached()) {
view.tip("提交成功!");
view.initSet();
SPUtils.remove(SubmitActivity.KEY_All);
}
}
});
}
/**
* @param submitBean
*/
private Boolean check(SubmitBean submitBean) {
if (TextUtils.isEmpty(submitBean.getEt1())) {
if (isViewAttached()) {
view.tip("et1 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt2())) {
if (isViewAttached()) {
view.tip("et2 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt3())) {
if (isViewAttached()) {
view.tip("et3 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt4())) {
if (isViewAttached()) {
view.tip("et4 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt5())) {
if (isViewAttached()) {
view.tip("et5 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt6())) {
if (isViewAttached()) {
view.tip("et6 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt7())) {
if (isViewAttached()) {
view.tip("et7 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt8())) {
if (isViewAttached()) {
view.tip("et8 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt9())) {
if (isViewAttached()) {
view.tip("et9 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt10())) {
if (isViewAttached()) {
view.tip("et10 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt11())) {
if (isViewAttached()) {
view.tip("et11 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt12())) {
if (isViewAttached()) {
view.tip("et12 null");
}
return false;
}
if (TextUtils.isEmpty(submitBean.getEt13())) {
if (isViewAttached()) {
view.tip("et13 null");
}
return false;
}
return true;
}
public void initSet() {
if (isViewAttached()) {
view.initSet();
}
}
public void save(SubmitBean submitBean) {
if (isViewAttached()) {
view.save();
}
}
public void attachView(ISubmitView v) {
this.view = v;
}
public void detachView() {
this.view = null;
}
public boolean isViewAttached() {
return view != null;
}
}
SubmitActivity.calss
public class SubmitActivity extends AppCompatActivity implements ISubmitView, View.OnClickListener {
// Content View Elements
private Button mBtn1;
private Button mBtn2;
private Button mBtn3;
private EditText mEt1;
private EditText mEt2;
private EditText mEt3;
private EditText mEt4;
private EditText mEt5;
private EditText mEt6;
private EditText mEt7;
private EditText mEt8;
private EditText mEt9;
private EditText mEt10;
private EditText mEt11;
private EditText mEt12;
private EditText mEt13;
private ISubmitPresenter presenter;
public static final String KEY_All = "All";
private void bindViews() {
mBtn1 = (Button) findViewById(R.id.btn1);
mBtn2 = (Button) findViewById(R.id.btn2);
mBtn3 = findViewById(R.id.btn3);
mEt1 = (EditText) findViewById(R.id.et1);
mEt2 = (EditText) findViewById(R.id.et2);
mEt3 = (EditText) findViewById(R.id.et3);
mEt4 = (EditText) findViewById(R.id.et4);
mEt5 = (EditText) findViewById(R.id.et5);
mEt6 = (EditText) findViewById(R.id.et6);
mEt7 = (EditText) findViewById(R.id.et7);
mEt8 = (EditText) findViewById(R.id.et8);
mEt9 = (EditText) findViewById(R.id.et9);
mEt10 = (EditText) findViewById(R.id.et10);
mEt11 = (EditText) findViewById(R.id.et11);
mEt12 = (EditText) findViewById(R.id.et12);
mEt13 = (EditText) findViewById(R.id.et13);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_submit);
bindViews();
presenter = new ISubmitPresenter(this, new ISubmitModel());
mBtn1.setOnClickListener(this);
mBtn2.setOnClickListener(this);
mBtn3.setOnClickListener(this);
setCache();
}
private void setCache() {
String value = (String) SPUtils.get(KEY_All, "");
if (!TextUtils.isEmpty(value)) {
SubmitBean sb = new Gson().fromJson(value, SubmitBean.class);
if (sb == null) {
return;
}
mEt1.setText(sb.getEt1());
mEt2.setText(sb.getEt2());
mEt3.setText(sb.getEt3());
mEt4.setText(sb.getEt4());
mEt5.setText(sb.getEt5());
mEt6.setText(sb.getEt6());
mEt7.setText(sb.getEt7());
mEt8.setText(sb.getEt8());
mEt9.setText(sb.getEt9());
mEt10.setText(sb.getEt10());
mEt11.setText(sb.getEt11());
mEt12.setText(sb.getEt12());
mEt13.setText(sb.getEt13());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
presenter.detachView();
}
@Override
public void initSet() {
mEt1.setText("");
mEt2.setText("");
mEt3.setText("");
mEt4.setText("");
mEt5.setText("");
mEt6.setText("");
mEt7.setText("");
mEt8.setText("");
mEt9.setText("");
mEt10.setText("");
mEt11.setText("");
mEt12.setText("");
mEt13.setText("");
}
@Override
public void tip(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void save() {
SPUtils.put(KEY_All, new Gson().toJson(getSubmitBean()));
tip("保存成功!");
}
@NonNull
private SubmitBean getSubmitBean() {
return new SubmitBean(
getText(mEt1),
getText(mEt2),
getText(mEt3),
getText(mEt4),
getText(mEt5),
getText(mEt6),
getText(mEt7),
getText(mEt8),
getText(mEt9),
getText(mEt10),
getText(mEt11),
getText(mEt12),
getText(mEt13));
}
private String getText(EditText et) {
return et.getText().toString().trim();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn1:
presenter.submit(getSubmitBean());
break;
case R.id.btn2:
presenter.initSet();
break;
case R.id.btn3:
presenter.save(getSubmitBean());
break;
default:
break;
}
}
}
其他SubmitBean实体类
public class SubmitBean {
private String et1;
private String et2;
private String et3;
private String et4;
private String et5;
private String et6;
private String et7;
private String et8;
private String et9;
private String et10;
private String et11;
private String et12;
private String et13;
public String getEt1() {
return et1;
}
public void setEt1(String et1) {
this.et1 = et1;
}
public String getEt2() {
return et2;
}
public void setEt2(String et2) {
this.et2 = et2;
}
public String getEt3() {
return et3;
}
public void setEt3(String et3) {
this.et3 = et3;
}
public String getEt4() {
return et4;
}
public void setEt4(String et4) {
this.et4 = et4;
}
public String getEt5() {
return et5;
}
public void setEt5(String et5) {
this.et5 = et5;
}
public String getEt6() {
return et6;
}
public void setEt6(String et6) {
this.et6 = et6;
}
public String getEt7() {
return et7;
}
public void setEt7(String et7) {
this.et7 = et7;
}
public String getEt8() {
return et8;
}
public void setEt8(String et8) {
this.et8 = et8;
}
public String getEt9() {
return et9;
}
public void setEt9(String et9) {
this.et9 = et9;
}
public String getEt10() {
return et10;
}
public void setEt10(String et10) {
this.et10 = et10;
}
public String getEt11() {
return et11;
}
public void setEt11(String et11) {
this.et11 = et11;
}
public String getEt12() {
return et12;
}
public void setEt12(String et12) {
this.et12 = et12;
}
public String getEt13() {
return et13;
}
public void setEt13(String et13) {
this.et13 = et13;
}
public SubmitBean(){}
public SubmitBean(String et1, String et2, String et3, String et4, String et5, String et6, String et7, String et8, String et9, String et10, String et11, String et12, String et13) {
this.et1 = et1;
this.et2 = et2;
this.et3 = et3;
this.et4 = et4;
this.et5 = et5;
this.et6 = et6;
this.et7 = et7;
this.et8 = et8;
this.et9 = et9;
this.et10 = et10;
this.et11 = et11;
this.et12 = et12;
this.et13 = et13;
}
@Override
public String toString() {
return "{" +
"et1='" + et1 + '\'' +
", et2='" + et2 + '\'' +
", et3='" + et3 + '\'' +
", et4='" + et4 + '\'' +
", et5='" + et5 + '\'' +
", et6='" + et6 + '\'' +
", et7='" + et7 + '\'' +
", et8='" + et8 + '\'' +
", et9='" + et9 + '\'' +
", et10='" + et10 + '\'' +
", et11='" + et11 + '\'' +
", et12='" + et12 + '\'' +
", et13='" + et13 + '\'' +
'}';
}
}
submit.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="提交" />
<Button
android:id="@+id/btn2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="初始化" />
<Button
android:id="@+id/btn3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="保存" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/et1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et1" />
<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et2" />
<EditText
android:id="@+id/et3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et3" />
<EditText
android:id="@+id/et4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et4" />
<EditText
android:id="@+id/et5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et5" />
<EditText
android:id="@+id/et6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et6" />
<EditText
android:id="@+id/et7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et7" />
<EditText
android:id="@+id/et8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et8" />
<EditText
android:id="@+id/et9"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et9" />
<EditText
android:id="@+id/et10"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et10" />
<EditText
android:id="@+id/et11"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et11" />
<EditText
android:id="@+id/et12"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et12" />
<EditText
android:id="@+id/et13"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="et13" />
</LinearLayout>
</ScrollView>
</LinearLayout>
封装简化mvp
MvpBaseView.class 作为所有View基类
public interface MvpBaseView {
}
MvpBasePresenter.class 业务处理基类
public class MvpBasePresenter<V extends MvpBaseView> {
private V v;
public void attachView(V v) {
this.v= v;
}
public void detachView() {
this.v= null;
}
public boolean isViewAttached(){
return v!= null;
}
/**
* 获取V层
* @return
*/
public V getmMvpView() {
return v;
}
}
MvpBaseActivity.class mvp中Activity处理
public abstract class MvpBaseActivity<V extends MvpBaseView, P extends MvpBasePresenter<V>> extends AppCompatActivity implements MvpBaseView {
private P presenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(initLayout());
if (presenter == null) {
presenter = createPresenter();
}
//绑定view
presenter.attachView((V) this);
initEvent();
}
protected abstract void initEvent();
protected abstract int initLayout();
@Override
protected void onDestroy() {
super.onDestroy();
//解除绑定
if (presenter != null) {
presenter.detachView();
}
}
/**
* 创建Presenter
* @return 子类自己需要的Presenter
*/
protected abstract P createPresenter();
/**
* 获取Presenter
* @return 返回子类创建的Presenter
*/
public P getPresenter() {
return presenter;
}
}
MvpBaseFragment.class
public abstract class MvpBaseFragment<V extends MvpBaseView, P extends MvpBasePresenter<V>> extends Fragment implements MvpBaseView{
private P presenter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view=inflater.inflate(initLayout(),null);
initEvent();
return view;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (presenter == null) {
presenter = createPresenter();
}
//绑定view
presenter.attachView((V) this);
}
protected abstract void initEvent();
protected abstract int initLayout();
@Override
public void onDestroyView() {
super.onDestroyView();
//解除绑定
if (presenter != null) {
presenter.detachView();
}
}
/**
* 创建Presenter
* @return 子类自己需要的Presenter
*/
protected abstract P createPresenter();
/**
* 获取Presenter
* @return 返回子类创建的Presenter
*/
public P getPresenter() {
return presenter;
}
}
使用mvp之后登录处理
IMode.class 基本不变
public class IMode {
/**
* 登录接口
* @param url
* @param map
* @param callback
*/
public void login(String url, Map map , StringCallback callback){
OkHttpManager.get(url,map).execute(callback);
}
/**
* 获取当前站点接口
*/
public void getNowWhere(String url,StringCallback callback){
OkHttpManager.get(url).execute(callback);
}
}
MvpBaseView.calss
public interface IView extends MvpBaseView {
void show();
void hide();
void toMainActivity();
void tip(String msg);
}
LoginActivity.class
public class LoginActivity extends MvpBaseActivity<IView,IPresenter> implements IView,View.OnClickListener{
private ProgressDialog progressDialog;
private EditText et_name;
private EditText et_password;
private Button btn;
@Override
protected IPresenter createPresenter() {
return new IPresenter(this,new IMode());
}
@Override
protected void initEvent() {
et_name=findViewById(R.id.username);
et_password=findViewById(R.id.password);
btn=findViewById(R.id.btn);
btn.setOnClickListener(this);
progressDialog=new ProgressDialog(this);
progressDialog.setCancelable(false);
progressDialog.setMessage("正在请求...");
}
@Override
protected int initLayout() {
return R.layout.activity_main;
}
@Override
public void show() {
progressDialog.show();
}
@Override
public void hide() {
progressDialog.hide();
}
@Override
public void toMainActivity() {
startActivity(new Intent(this, HomeActivity.class));
}
@Override
public void tip(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn:
String name=et_name.getText().toString().trim();
String password=et_password.getText().toString().trim();
getPresenter().login(name,password);
break;
default:
break;
}
}
}
其实也就是省去注销P以及约束V…