点击上方蓝字关注 ??
来源:https://www.jianshu.com/p/8996c57168e3
详解
这个框架在项目的使用中已经有好一段时间了,于是把其中基本的模块抽取出来写出来。
demo结构图:
搭建流程:
引入所需依赖库:
//Rxjava
implementation 'io.reactivex:rxjava:1.1.0'
implementation 'io.reactivex:rxandroid:1.1.0'//Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
implementation 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
implementation 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta4'//Gson
implementation 'com.google.code.gson:gson:2.6.2'
使用Retrofit+Rxjava
1.请求接口地址以及声明类:
功能是初始化retrofit和okhttp;设置okhttp的header拦截器、请求数据拦截器、请求缓存拦截器。
public interface ApiService {/** 正式服务器地址 */String SERVER_ADDRESS_RELEASE = "";/** 测试服务器地址 */String SERVER_ADDRESS_DEBUG = "";/** 服务器域名 */String SERVER_ADDRESS = isDebug ? SERVER_ADDRESS_DEBUG : SERVER_ADDRESS_RELEASE;@GET("")
Observable> getVideoData();
}
2.单例的Retrofit和Okhttp管理类
单例模式创建ApiService类,添加服务器地址,设置5秒请求超时。ApiService默认返回Call类型,但是需要直接转化Observable类型,此时需要添加addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 。需要直接转化为需要的实体类,需要添加addCallAdapterFactory(RxJavaCallAdapterFactory.create())
public class ApiManager {private static ApiManager mApiManager;private OkHttpClient mOkHttpClient;private static ApiService mApiService;private final int TIMEOUT = 10;private ApiManager() {
initOkhttp();
initRetrofit();
}public static synchronized ApiService getApiService() {if (mApiService == null) {
mApiManager = new ApiManager();
}return mApiService;
}private void initOkhttp() {
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS) //连接超时设置
.readTimeout(TIMEOUT, TimeUnit.SECONDS) //写入缓存超时10s
.writeTimeout(TIMEOUT, TimeUnit.SECONDS) //读取缓存超时10s
.retryOnConnectionFailure(true) //失败重连
.addInterceptor(new HeaderInterceptor()) //添加header
.addInterceptor(new NetCacheInterceptor()); //添加网络缓存
addLogIntercepter(builder); //日志拦截器
setCacheFile(builder); //网络缓存
mOkHttpClient = builder.build();
}private void initRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiService.SERVER_ADDRESS)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.client(mOkHttpClient)
.build();
mApiService = retrofit.create(ApiService.class);
}/**
* 设置缓存文件路径
*/private void setCacheFile(OkHttpClient.Builder builder) {//设置缓存文件
File cacheFile = new File(DirConfig.HTTP_CACHE);//缓存大小为10Mint cacheSize = 10 * 1024 * 1024;
Cache cache = new Cache(cacheFile,cacheSize);
builder.cache(cache);
}/**
* 调试模式下加入日志拦截器
* @param builder
*/private void addLogIntercepter(OkHttpClient.Builder builder) {if (AppConfig.isDebug) {
builder.addInterceptor(new LoggingInterceptor());
}
}
}
3.给okhttp添加拦截器
统一添加header的拦截器:
public class HeaderInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("token", UserInfoCache.TOKEN);return chain.proceed(builder.build());
}
}
Okhttp返回数据日志拦截器:
public class LoggingInterceptor implements Interceptor {private final int byteCount = 1024*1024;@Overridepublic Response intercept(Chain chain) throws IOException {//chain里面包含了request和response,按需获取
Request request = chain.request();
Response response = chain.proceed(request);
LogUtils.d(String.format("发送请求 %s",request.url()));
ResponseBody responseBody = response.peekBody(byteCount);
LogUtils.d(String.format("接收响应 %s", responseBody.string()));return response;
}
}
网络拦截器进行网络缓存:
public class NetCacheInterceptor implements Interceptor {@Overridepublic Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);int onlineCacheTime = 60;return response.newBuilder()
.header("Cache-Control", "public, max-age="+onlineCacheTime)
.removeHeader("Pragma")
.build();
}
}
4.自定义请求数据回调和过滤:
封装泛型实体类的观察者,统一处理结果。请求成功给下一层返回实体类。请求失败从HttpException中获取code设置对应的errorMsg
public abstract class ApiCallBack<M extends BaseModel> extends Subscriber<M> {@Overridepublic void onCompleted() { }@Overridepublic void onError(Throwable e) {
e.printStackTrace();if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;int code = httpException.code();//Http状态码提示if (code >=400 && code< 500) {
LogUtils.e("请求错误");
} else if (code >= 500) {
LogUtils.e("服务器错误");
}
}
}@Overridepublic void onNext(M baseModel) {
handleStatusCode(baseModel);
}/**
* 后台statuscode状态码处理,状态码类型封装在StatusCodeEnum中
* @param baseModel
*/private void handleStatusCode(M baseModel) {
String statusCode = baseModel.code;
StatusCodeEnum statusCodeEnum = StatusCodeEnum.getByCode(statusCode);switch (statusCodeEnum) {case RESULT_OK: //请求成功
onSuccess(baseModel);break;case RESULT_TOKENINVALID: //token失效// TODO: 2018/11/23 token失效,删除本地用户信息储存并退出登录break;default:
LogUtils.e("请求失败错误");break;
}
}/**
* onSuccess回调的数据为程序具体需要的业务状态码,具体数据等
*/public abstract void onSuccess(M m);
}
详解MVP加入
1.View
Iview类:规定所有Activity,fragment等容器的公共行为,例如显示加载框和隐藏
public interface IView {void showLoading();void hideLoading();
}
IBaseView:
public interface IBaseView<M extends BaseModel> extends IView {
}
2.presenter
Ipresenter:
public interface Ipresenter<V extends IView> {/**
* 关联P与V
* @param v
*/void attachView(V v);/**
* 取消关联P与V
*/void detachView();/**
* Rx订阅
*/void subscribe(Observable observable, Subscriber subscriber);/**
* Rx取消订阅
*/void unSubscribe();
}
BasePresenter:Basepresenter,抽象的persenter业务处理层。关联抽象层view和抽象model,通过CompositeSubscription关联数据请求,并通过subscriber回调回view层。
public class BasePresenter<V extends IBaseView> implements Ipresenter<V> {protected V view;protected ApiService apiService;protected CompositeSubscription mCompositeSubscription;@Overridepublic void attachView(IBaseView v) {this.view = (V) v;
apiService = ApiManager.getApiService();
}@Overridepublic void detachView() {this.view = null;
unSubscribe();
}@Overridepublic void subscribe(Observable observable, Subscriber subscriber) {if (mCompositeSubscription == null) {
mCompositeSubscription = new CompositeSubscription();
}//绑定observable与subscriber
Subscription subscription = observable.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(subscriber);
mCompositeSubscription.add(subscription);
}@Overridepublic void unSubscribe() {if (mCompositeSubscription != null && mCompositeSubscription.hasSubscriptions()) {
mCompositeSubscription.unsubscribe();
}
}
}
3.Model
BaseModel:请求数据实体类基类,对需要的data数据进行泛型处理
public class BaseModelimplements IModel,Serializable {/** 自定义错误码 */public String code;/** 自定义业务状态码 */public String bizcode;/** 消息提示 */public String msg;/** 泛型实体类 */public T data;public boolean isOk() {return bizcode.equals(AppConfig.BIZCODE_OK);
}
}
4.MvpActivity基类:
MvpActivity绑定presenter,在销毁时解绑,调用onUnsubscribe()将rxjava统一取消注册,以避免内存泄露。至于BaseActivity功能根据项目业务需求进行封装。比如跳转,加载弹出框,是否全屏,频繁调用工具类等。
public abstract class BaseMvpActivity<P extends BasePresenter> extends AppCompatActivity {protected P mPresenter;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {
mPresenter = createPresenter();super.onCreate(savedInstanceState);
}protected abstract P createPresenter();@Overrideprotected void onDestroy() {super.onDestroy();//页面销毁时取消presenter绑定if (mPresenter != null) {
mPresenter.detachView();
}
}
}
实现MainActivity的功能:
1.MainView:
public interface MainView extends IBaseView {void getVideoData(BaseModel videoBeanBaseModel);
}
2.MainPresenter:
public class MainPresenter extends BasePresenter<MainView> {public MainPresenter(MainView mainView) {
attachView(mainView);
}public void getVideoData() {
view.showLoading();
subscribe(apiService.getVideoData(), new ApiCallBack>() {@Overridepublic void onSuccess(BaseModel videoBeanBaseModel) {
view.hideLoading();
view.getVideoData(videoBeanBaseModel);
}
});
}
}
3.MainActivity:
public class MainActivity extends BaseMvpActivity<MainPresenter> implements MainView{private TextView tvContent;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvContent = findViewById(R.id.tv_content);
mPresenter.getVideoData();
}@Overrideprotected MainPresenter createPresenter() {return new MainPresenter(this);
}@Overridepublic void showLoading() {
}@Overridepublic void hideLoading() {
}@Overridepublic void getVideoData(BaseModel videoBeanBaseModel) {
tvContent.setText(videoBeanBaseModel.data.toString());
}
}
好的,打完收工。
Github地址:
https://github.com/18380438200/MvpFrameUpdate
—————END—————