古语有云,没有规矩,就不成方圆。其实做什么事都一样,做什么事都要有自己熟悉且大家都认同的一套规矩,这样既能提高自己的做事效率,也方便他人的理解。
在移动开发中,mvp是新兴的一种软件开发模式,是经过时间的考验并且大家都认同的解耦框架。它不仅能让我们的代码逻辑更加清晰,不同层间分工不同又相互协作,服务于我们的项目。mode层负责本地数据和网络数据的处理,presenter层负责业务逻辑的处理,view层负责ui界面的展示。减少了view层与model层的直接交互,而是通过presenter实现中间代理的交互逻辑。
rxjava+retrofit是最近很火的网络层框架,两者完美协作客户端与服务器的数据交互,并且rxjava是响应式编程代表,在retrofit提供网络服务的时候方便的切换处理线程,大大方便了客户端网络层的开发。
dagger2是android端的依赖注入框架,做过ssh的同学可能不会陌生,有了依赖注入的思想,不用我们自己通过new的方式去创建对象了,而是通过注入,将对象托管权交出来由容器统一管理,而当我们需要的时候直接从容器中去取(如果用传统的方式通过new的方式创建实例对象,当类构造函数或内部发生改变后,每个new的地方都需要去改变,工作量可见之大。而通过依赖注入的方式管理后,只需要很小的开销就能实现)。
磨刀不误砍柴工,在对rxjava+retrofit+mvp+dagger2进行了简单的了解之后,开始我们的基层框架搭建吧。
既然这是一个大量信息交互的时代,我们就从网络层框架开始搭建吧。实现rxjava+retrofit的网络层服务。
首先看一下最后的框架结构:
在gradle中需要添加如下依赖:
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:1.1.0'
compile 'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.okhttp3:logging-interceptor:3.3.0'
compile 'com.github.d-max:spots-dialog:0.7@aar'
接下来我们一次介绍每层的功能和实现原理:api层是进行网络请求的接口封装层,可以将网络请求的借口和参数等放入commonapi中进行统一管理,当我们通过retrofit创建出commonapi实例后,就可以对所有网络请求进行访问(当然也可以根据自己的需求和爱好进行分类)。看一下我的commonapi简单实现:根据page路径参数获取当前页的ip列表(get注解后为相对地址路径,baseurl在创建retrofit时指定)
public interface CommonApi {
@GET("allip/{page}")
Observable<TableIp> userLogin(@Path("page")int page);
}
接下来是exception包下面的内容,它主要处理网络请求过程中的异常。
(1)ApiError类是处理数据请求异常(如请求地址,参数等错误)时,对错误信息的封装。它根据服务器返回的不同的errorbody而异,本例中包含code和displayMessage两个字段,如下:
/*错误码*/
private int code;
/*显示的信息*/
private String displayMessage;
public ApiError(Throwable e) {
super(e);
}
public ApiError(Throwable cause,@CodeException.CodeEp int code, String showMsg) {
super(showMsg, cause);
setCode(code);
setDisplayMessage(showMsg);
}
// @CodeException.CodeEp
public int getCode() {
return code;
}
//@CodeException.CodeEp
public void setCode( int code) {
this.code = code;
}
public String getDisplayMessage() {
return displayMessage;
}
public void setDisplayMessage(String displayMessage) {
this.displayMessage = displayMessage;
}
(2)CodeException是请求失败时不同的errorcode(错误码)。
(3)HttpTimeException是对项目出现runtimeexception(运行时异常)时数据的封装,方便向用户展示错误信息,如下所示:
/*未知错误*/
public static final int UNKOWN_ERROR = 0x1002;
/*本地无缓存错误*/
public static final int NO_CHACHE_ERROR = 0x1003;
/*缓存过时错误*/
public static final int CHACHE_TIMEOUT_ERROR = 0x1004;
public HttpTimeException(int resultCode) {
this(getApiExceptionMessage(resultCode));
}
public HttpTimeException(String detailMessage) {
super(detailMessage);
}
/**
* 转换错误数据
*
* @param code
*