前言
之前总结了RxJava2.0&Retrofit2.0的使用,现在开发基本都会使用MVP模式,本来就打算写一篇MVP+RxJava2.0&Retrofit2.0的总结,然而写完RxJava2.0&Retrofit2.0后就在忙项目,终于忙完了就开始着手总结了。
然而在使用过程中发现,RxJava2.0&Retrofit2.0结合使用过程中需要导入大量的依赖,MVP的管理十分不便等等。
于是索性就尝试写一个MVP模式+RxJava2.0&Retrofit2.0框架(DeMon_MVPRR框架),由于是第一次写框架,加上自身水平有限,所以存在诸多不足,如果有任何疑问欢迎留言指正,楼主联系方式请看左边。
还不了解MVP模式+RxJava2.0&Retrofit2.0,请戳:
DeMon_MVPRR框架说明
DeMon_MVPRR框架GitHub地址:
DeMon_MVPRR框架Demo示例,GitHub地址:
引入依赖
工程build.gradle中,添加:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
项目build.gradle中,添加:
dependencies {
....
compile 'com.github.DeMonLiu623:DeMon_MVPRR:v1.3'
...
}
添加网络相关权限:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
本框架的优点
- 在Retrofit的基础上利用OKHttp配置了缓存及超时策略。
- 封装了RxJava的订阅及线程调度过程,减少了RxJava使用过程中的代码量。
- 利用RxJava的订阅过程结合Handler机制,在网络请求耗时的时候封装了一个ProgressDialog,增加了用户体验。
- 根据谷歌官方的MVP文档,采用Contract管理Presenter和View接口,使用起来更方便。
- 封装了基础的Model,Presenter,View interface,View(Activity),进一步解耦,方便了MVP的调用,减少了实例化操作,释放内存。
框架包含依赖
dependencies {
compile 'io.reactivex.rxjava2:rxjava:2.1.3' //RxJava2.0所需依赖
compile 'com.squareup.retrofit2:retrofit:2.3.0' //Retrofit2.0所需依赖
compile 'com.squareup.retrofit2:converter-gson:2.3.0' //结果转为实体类所需依赖
compile 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' //RxJava2.0+Retrofit2.0适配依赖
compile 'io.reactivex.rxjava2:rxandroid:2.0.1'//Rxandroid2.0线程调度依赖
compile 'com.squareup.okhttp3:okhttp:3.9.0' //OKHttp3.0依赖
compile 'com.squareup.okhttp3:logging-interceptor:3.9.0' //OKHttp优化策略依赖
compile 'com.squareup.retrofit2:converter-scalars:2.3.0' //结果转为基本类型所需依赖
compile 'com.jakewharton:butterknife:8.5.1' //组件视图绑定依赖
compile 'com.jakewharton:butterknife-compiler:8.5.1'//组件视图绑定依赖
compile 'com.android.support:design:26.0.0-alpha1' //design依赖
}
添加本框架的依赖后,上面依赖无需重复添加。
框架实现说明
框架目录结构如下:
主要讲解各个类的作用,不再贴出代码详解。
看代码请直接戳DeMon_MVPRR
代码如有不明请戳DeMon_MVPRR框架基础知识笔记
BaseApplication.java
主要包含一个getContext()方法,用于获取全局的上下文。
BaseApi.java
主要利用OKHttp配置了缓存及超市策略,封装了获取Retrofit实例化对象过程。
两个方法:
- BaseApi.getRetrofit(String baseUrl)获取策略优化的Retrofit实例。
- BaseApi.getSimpleRetrofit(String baseUrl)获取简单的无策略优化的Retrofit实例。
PS:为了适应大部分情况,适应了OKHttp增加了Json头部数据格式,本框架默认将请求数据打包成Json格式发送,因此本框架不适用于不允许发送Json数据请求的Api。
BaseModel.java
封装了线程管理和订阅的过程。
BasePresenter.java
BasePresenter的代码比较重要,贴出来。
public abstract class BasePresenter<T extends BaseView> {
protected WeakReference<T> mView;
protected BaseModel mModel = new BaseModel();
protected Context mContext;
public BasePresenter(T view) {
mView = new WeakReference<>(view);
}
public T getView() {
return mView.get();
}
//释放view及model的内存空间
public void onDestroy() {
if (mView != null) {
mView.clear();
mView = null;
}
if (mModel != null) {
mModel = null;
}
}
}
- 采用WeakReference管理View,便于View的释放。
- 实例化BaseModel,方便调用,减少实例化次数。
- Context对象会在BaseActivity中使用,方便子类调用。
- getView()获取实例化后的View interface对象,便于接口调用。
- onDestroy()及时释放view及model的内存空间.
BaseActivity.java&BaseTopBarActivity.java
- 结合Presenter,封装了Presenter初始化过程
- 重写onDestroy()方法释放View interface的所占用的内存。
- 采用抽象类+方法,减少了创建Activity过程的代码量。
- 实例化了Context对象,减少实例化次数。
- BaseTopBarActivity在BaseActivity的基础上增加了标题栏的封装,减少我们在使用标题栏过程中大量的xml布局代码。
继承了BaseTopBarActivity的子类,可以调用如下方法修改标题栏属性中:
1.setTopBarText(String text)标题栏标题内容,默认为空
2.setTopBarColor(int colorId) 标题栏标题内容的字体颜色,默认为白色
3.setToolbarBackground(int colorId) 标题栏背景颜色,默认为系统主题颜色
PS:继承了BaseTopBarActivity的子类Activty应该使用NoActionBar的主题,避免标题栏冲突。
BaseView.java
用于实例化View interface对象。
ObserverOnNextListener.java
用于监听订阅过程中onNext(T t)方法,接口回调获取请求结果。
ProgressCancelListener.Java
- 用于监听请求失败时,关闭ProgressDialog.
- 用户手动关闭ProgressDialog时,终端并取消网络请求
ProgressDialogHandler.java
继承Handler,实现ProgressDialog功能,初始实话ProgressDialog。
ProgressObserver.java
RxJava的订阅过程。
1. 控制ProgressDialog的显示与隐藏。
2. 利用ObserverOnNextListener监听onNext(T t)实现请求结果回调。
NetWorkUtil.java
监听及判断网络状态,用于根据网络状态配置OkHttp策略。
框架使用Demo
成功引入了框架的依赖后,接下来讲解一下具体如何使用。
Demo的GitHub代码地址:https://github.com/DeMonLiu623/MVPRRDemo
Demo的Api:
“http://gc.ditu.aliyun.com/“;//阿里云根据地区名获取经纬度接口
Demo结构目录:
1.创建ApiService类
用于Retrofit管理Api及请求参数。
public interface ApiService {
@GET("geocoding")
Observable<String> getLocation(@Query("a") String a);//获取的请求结果为String
@GET("geocoding")
Observable<City> getCity(@Query("a") String a);//获取的请求结果为实体类型
}
2.创建Api类
- 强烈建议使用单例模式获取ApiService实例。
- 根据RESTful API配置baseUrl。
public class Api {
private String baseUrl = "http://gc.ditu.aliyun.com/";//阿里云根据地区名获取经纬度接口
public volatile static ApiService apiService;
public static ApiService getApiService() {
if (apiService == null) {
synchronized (Api.class) {
if (apiService == null) {
new Api();
}
}
}
return apiService;
}
public Api() {
BaseApi baseApi = new BaseApi();
apiService = baseApi.getRetrofit(baseUrl).create(ApiService.class);
}
}
3.创建Contract类
根据谷歌官方的MVP模式,建议我们使用Contract来管理MVP模式。
所以Demo也采用这种方式。
当然你也可以不这么写,直接让Presenter继承BasePresenter。
public interface MainContract {
interface View extends BaseView {
void result(String s);
}
abstract class Presenter extends BasePresenter<View> {
public Presenter(View view) {
super(view);
}
public abstract void getLocation(String city);
}
}
4.创建Presenter类
由于继承了BasePresenter,所以可以直接使用mModel&mContext。
使用mModel.Subscribe()直接调用Retrofit+RxJava过程。
直接使用Api.getApiService().getLocation(city)调用Api。
ObserverOnNextListener()监听请求结果。
getView().result()回调请求结果。
public class MainPresenter extends MainContract.Presenter {
private static final String TAG = "MainPresenter";
public MainPresenter(MainContract.View view) {
super(view);
}
@Override
public void getLocation(String city) {
mModel.Subscribe(mContext, Api.getApiService().getLocation(city), new ObserverOnNextListener() {
@Override
public void onNext(Object o) {
getView().result(o+"");
}
});
}
}
5.Activity
- extends BaseActivity 直接重写方法,减少代码量。
- implements MainContract.View获取回调结果。
public class MainActivity extends BaseActivity<MainPresenter> implements MainContract.View {
private static final String TAG = "MainActivity";
@BindView(R.id.text)
TextView text;
@BindView(R.id.click)
Button click;
//初始化指定的Presenter对象
@Override
public void initPresenter() {
mPresenter = new MainPresenter(this);
}
//布局文件
@Override
public int getLayoutId() {
return R.layout.activity_main;
}
//相当于Activity的OnCreate(),需要写在OnCreate()中的都可以写在init()方法内
@Override
public void init() {
mPresenter.getLocation("苏州市");
}
//处理回调结果
@Override
public void result(String s) {
text.setText(s);
}
@OnClick(R.id.click)
public void onViewClicked() {
startActivity(new Intent(this, SecondActivity.class));
}
}
6.Demo运行结果
总结
框架是基于GitHub+jitpack构建的,添加依赖多了一步,但是完全不影响使用。
第一次写框架,很多地方不完善,如果有疑问或者指正错误的,请戳https://demonliu623.github.io/about/
项目支持开源,请尽情的复制粘贴,但是请注明来源,谢谢!
最后,欢迎大家前来我的GitHub DeMon_MVPRR框架 fork&star。