Android MVP-编程思想2(代码实现初级版)
Posted 0 and 1
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android MVP-编程思想2(代码实现初级版)相关的知识,希望对你有一定的参考价值。
前言
通过一个小的登录功能模块案例,帮助大家了解MVP。最终实现一个结合Rxjava2,Retrofit 的MVP通用框架。代码放到github上。(如有错误之处,请在评论区指出,谢谢。如果感觉写的不错,请点赞,关注,谢谢。)
目录:
Android MVP-编程思想1(什么是MVC-MVP-MVVM模式?)
Android MVP-编程思想2(代码实现初级版)
Android MVP-编程思想3(内存泄露问题处理,基类封装,有没有必要再使用软引用?)
Android MVP-编程思想4(AOP思想-动态代理运用,反射创建M层实例对象)
Android MVP-编程思想5(如何处理多个P层的问题?)
Android MVP-编程思想6(依赖注入多个P层优化—注解,反射)
Android MVP-编程思想7(为什么使用代理类抽取通用方法而不是工具类?,基类BaseMvpFragment)
未完待续--------
android MVP-编程思想8(集成Rxjava2,Retrofit)
MVP 实战
那么我们下面就要将这个类中的代码改写为 MVP 的写法,回顾上面提及的 MVP 架构的思想,它是将 View 层与 Model 层彻底隔离,意味着 View 和 Model 都不再持对方的引用,它们通过一个第三者 Presenter 来代理事物的传递,所以 Presenter 层会持有 Model 与 View 层的引用,这是第一步。
第二步,是将它们之间的联系抽象出来,以接口的方式相互调用,所以 Model 、View、Presenter 各自拥有自己的接口和抽象方法,所以这就会无形的多出了三个接口类,这也就是 MVP 的缺点之一。所以,为了较少的创建接口类,我们就给这三层接口定义了一个契约接口,把它们更加紧密的结合在一起,方法查看,例如代码这样写:参考谷歌官方mvp案例todo-mvp
下面我们以登录功能为例行了解 MVP 架构的代码写法。
第一步
首先我们参考谷歌todo-mvp 写一个契约类,定义交互行为。契约类的目的是把MVP的行为定义放在一起,方便阅读和维护
public class LoginContract
/**
* V 定义View的行为,调用者是P
*/
interface IView
//登录成功跳转到主界面
void goToMainActivity();
//请求网络显示等待框
void showProgress(boolean isShow);
//显示提示框-登录失败,或其他提示信息
void showToast(String string);
/**
* P(中转站和数据处理者) 定义View与Model的交互行为,调用者是V。P做中转
*/
interface IPresenter
void onClickLogin(String username, String pwd);
/**
* M 数据提供者
*/
interface IModel
void getUserInfo(String username, String pwd, ICallBack callBack);
第二步,定义MVP行为接口的实现类
辅助类ICallBack,用来回调http请求的数据
public interface ICallBack<T>
void success(T data);
void error(String error);
M层的实现类LoginModel,提供数据,网络数据,本地数据
public class LoginModel implements LoginContract.IModel
@Override
public void getUserInfo(String username, String pwd, final ICallBack callBack)
//todo 模拟 http请求
Handler handler = new Handler();
Runnable runnable = new Runnable()
@Override
public void run()
callBack.success("成功");
;
handler.postDelayed(runnable, 2000);
V层的实现类LoginActivity,控制视图显示,要调用P层接口,所以要持有P对象的引用
public class LoginActivity extends AppCompatActivity implements LoginContract.IView
LoginContract.IPresenter mPresenter;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPresenter = new LoginPresenter(this);
findViewById(R.id.btn_login).setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
mPresenter.onClickLogin("xxx", "xxx");
);
@Override
public void goToMainActivity()
runOnUiThread(new Runnable()
@Override
public void run()
//todo 登录成功跳转到主界面
Log.i("mvp_", "登录成功跳转到主界面");
);
@Override
public void showProgress(boolean isShow)
if (isShow)
Log.i("mvp_", "显示等待框");
else
Log.i("mvp_", "隐藏等待框");
@Override
public void showToast(String str)
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
P层实现类LoginPresenter,是M和V交互的协调者,所以要持有M,V对象的引用
注意点:网络请求是耗时操作,我们 Presenter 层持有了 View 层的引用,也就是 Activity 的引用,在网络请求过程中,Activity被用户或者系统关闭,这时 View 相当于被摧毁了,如果不进行判断 View 引用是否为空,当数据返回时,就会造成空指针异常,所以每次都要进行判空才合理。
public class LoginPresenter implements LoginContract.IPresenter
private LoginContract.IModel mModel;
private LoginContract.IView mView;
public LoginPresenter(LoginContract.IView view)
this.mModel = new LoginModel();
this.mView = view;
@Override
public void onClickLogin(String username, String pwd)
mView.showProgress(true);
mModel.getUserInfo(username, pwd, new ICallBack<String>()
@Override
public void success(String data)
if (mView != null)
mView.showToast("登录成功");
mView.showProgress(false);
mView.goToMainActivity();
@Override
public void error(String error)
if (mView != null)
mView.showProgress(false);
mView.showToast("登录失败");
);
上面使用最简单的方式,演示了MVP的设计思想。目的是让大家理解,MVP模式是如何把业务逻辑,数据与V层进行分离的。再回想对比MVC是不是觉得MVP模式,职责分离的更清楚。
运行,点击登录按钮,打印日志如下:---------------------
2019-12-11 14:34:06.990 6376-6376/chongchong.wei.rx_retrofit_mvp I/mvp_: 显示等待框
2019-12-11 14:34:09.002 6376-6376/chongchong.wei.rx_retrofit_mvp I/mvp_: 隐藏等待框
2019-12-11 14:34:09.002 6376-6376/chongchong.wei.rx_retrofit_mvp I/mvp_: 登录成功跳转到主界面
当然上面的代码只是帮助大家理解MVP模式的思想,一些细节问题没有处理。下一节我们对代码进行优化,抽离,封装。
以上是关于Android MVP-编程思想2(代码实现初级版)的主要内容,如果未能解决你的问题,请参考以下文章
Android MVP-编程思想4(AOP思想-动态代理运用,反射创建M层实例对象)
Android MVP-编程思想5(如何处理多个P层的问题?)
Android MVP-编程思想5(如何处理多个P层的问题?)
Android MVP-编程思想6(依赖注入多个P层方式优化---注解,反射)