【android进阶篇】【android进阶篇】MVP+Retrofit+RxJava框架结合
另一篇MVP优化,[android进阶篇]MVP模式优化,防止内存泄漏和空指针问题
一、前言
MVP模式是当前比较主流的框架,主要是由它的优点来决定的吧。本文结合了MVP+Retrofit+RxJava三大主流框架(MVP应该叫模式吧)写了一个demo【里面从简单的“登录”例子,之后到“IP地址查询”,再到相对贴近实际项目的“获取豆瓣TOP250的电影”】,一开始可能会觉得不容易理解,但是真正理解了之后,开发、维护就不是那么痛苦的事情了。
二、Demo介绍
2.1、需要具备哪些知识
读这篇文章之前,你需要了解的知识有:
1、MVP【点这里看百度百科介绍】
2、Retrofit 2.0
3、RxJava(点击这里看—不错的一个Retrofit+RxJava结合的例子)
4、Butterknife的使用
5、状态栏一体化(android状态栏一体化)
6、CallBack回调思想(说白了就是:成功还是失败了,你总的告诉我一声,我好通知V层来处理[这里可以不用回调,在代码中使用EventBus或者传递一个Handler过来也可以,不建议这样操作])
2.2、Demo中使用到的工具类、技术
- MVP 模式
- Retrofit 网络请求
- RxJava 异步
- Klog 花样日志
- CallBack 回调思想 丢弃Handler
- RecycleView 高效地显示大量数据—>未来替代listview gridview的控件
- CommonAdapter 鸿洋大神的RecycleView通用适配器
- Loadmore 加载更多 也是借助鸿洋大神的RecycleView通用适配器(添加FootHeader)实现的
- Glide 高效的图片加载库
- android-Ultra-Pull-To-Refresh 下拉刷新
- ClearEditText 自定义”带清除所有内容”的输入框控件
- 状态栏一体化(设置状态栏的颜色与app主题色一致 没有过渡感)
2.3、优势
1、MVP 高度解耦 提高代码质量
2、Retrofit+RxJava最强的网络访问组合
3、功能易扩展 易维护 易测试
2.4、数据源
豆瓣TOP250的电影 https://api.douban.com/v2/movie/top250?start=0&count=10
查询IP地址 http://ip.taobao.com/service/getIpInfo.php?ip=1.1.1.1
2.5、MVP浅析
1)、MVP的优点:
1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter内部
3、我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)【以上优点参考了百度百科的“MVP模式“】
2)、以登录为例的MVP自理解图
2.6、当下最快的网络访问(Retrofit +RxJava)
用熟悉之后你会发现,网络访问就是这么简单,这么快.优点我就不一一说了,网上太多的介绍.
三、效果图与分包说明
3.1、效果图
不多说,先来看效果图
3.2、分包说明
分包有很多种分法,我这里用了我常用的分包方法,仅供参考。
说明:adapter–>适配器的类,base–>基础的配置类,bean–>实体对象,exception–>异常处理对象,http–>网络相关,ui–>所有的页面(包括fragment【/ui/fragment】),utils–>工具类,widget–>自定义控件类。
3.3、其他说明
Demo阅读指南 :先看登录的Demo(入门),理解之后再看IP地址查询(深入),最后看获取豆瓣TOP250的电影(浅出)
使用第三方库说明 :为了快速写出这个demo,在一些方便走了捷径(有时间的可以自己用原生的写法),比如RecycleView的适配器,我就用了鸿洋大神的通用适配器(CommonAdapter),还有使用Butterknife来代替findviewbyid,但是看过郭霖大神写的性能优化一篇博客,说是实际开发中最好慎重使用依赖注入,会降低app的性能和效率,我在这里为了方便就直接使用了.
四、登录demo
4.1、布局
布局简单就不贴了
4.2、接口类
为什么要使用接口,之前已经说过了,这里之所以写在一个类中,也是为了便于管理,不至于项目看上去有太多的类。
/**
* 登录的关联类
* Created by HDL on 2016/7/22.
*/
public class LoginContract {
/**
* V视图层
*/
interface ILoginView {
Context getCurContext();//获取上下文对象,用于保存数据等
void showProgress();//可以显示进度条
void hideProgress();//可以隐藏进度条
void showInfo(String info);//提示用户,提升友好交互
void showErrorMsg(String msg);//发生错误就显示错误信息
void toMain();//跳转到主页面
void toRegister();//跳转到注册页面
UserInfo getUserLoginInfo();//获取用户登录信息
}
/**
* P视图与逻辑处理的连接层
*/
interface ILoginPresenter {
void login();//桥梁就是登录了
}
/**
* 逻辑处理层
*/
interface ILoginModel {
void login(UserInfo userInfo, OnHttpCallBack<TokenResult> callBack);//登录
void saveUserInfo(Context context, UserInfo user,String token);//登录成功就保存用户信息
}
4.3、View层(LoginActivity)
展示数据,处理用户交互
/**
* 登录页面
* (看例子之前看一遍下面直白的解释,看完之后再看一遍就更明白MVP模式了)
* --------M层 对P层传递过来的userInfo进行登录(网络请求)判断,处理完成之后将处理结果回调给P层
* --------P层 传递完数据给M层处理之后,实例化回调对象,成功了就通知V层登录成功,失败了就通知V层显示错误信息
* --------V层 负责响应用户的交互(获取数据---->提示操作结果)
*/
public class LoginActivity extends BaseActivity implements LoginContract.ILoginView {
//省略ButterKnife绑定页面控件的代码
private LoginPresenter mLoginPresenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
ButterKnife.inject(this);
tvTitle.setText("用户登录");
mLoginPresenter = new LoginPresenter(this);
}
@Override
public Context getCurContext() {
return mActivity;
}
@Override
public void showProgress() {
pbProgress.setVisibility(View.VISIBLE);
}
@Override
public void hideProgress() {
pbProgress.setVisibility(View.GONE);
}
@Override
public void showInfo(String info) {
ToastUtils.showToast(mActivity, info);
}
@Override
public void showErrorMsg(String msg) {
ToastUtils.showToast(mActivity, msg);
}
@Override
public void toMain() {
startActivity(new Intent(mActivity, QueryIPActivity.class));
}
@Override
public void toRegister() {
startActivity(new Intent(mActivity, RegisterActivity.class));
}
@Override