您的位置:首页 > 理论基础 > 计算机网络

retrofit+mvp+okhttp+rxjava封装

2018-02-28 17:08 429 查看
首先是retrofit和okhttp的封装:
因为retrofit的底层就是用okhttp请求网络的,所以可以通过就是设置okhttp的连接超时,缓存,日志等,将它加入到retrofit中。
具体代码:import android.content.Context;
import android.util.Log;

import com.jakewharton.retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import com.seehealth.easynet.http.RetrofitService;
import com.seehealth.easynet.http.ServiceConfig;

//import org.simpleframework.xml.Serializer;
//import org.simpleframework.xml.convert.AnnotationStrategy;
//import org.simpleframework.xml.core.Persister;
//import org.simpleframework.xml.strategy.Strategy;

import java.io.File;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
//import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

/**
* Created by ljj on 2017/9/29.
*/

public class RetrofitManager {

private volatile static RetrofitManager retrofitManager;
private RetrofitService retrofitService;

// private static Strategy strategy = new AnnotationStrategy();
// private static Serializer serializer = new Persister(strategy);

private RetrofitManager(Context context) {
OkHttpClient okHttpClient = initOkHttpClient(context);
Retrofit retrofit = initRetrofit(okHttpClient);
retrofitService = retrofit.create(RetrofitService.class);
}

public static RetrofitManager getInstance(Context context) {
if (retrofitManager == null) {
synchronized (RetrofitManager.class) {
if (retrofitManager == null) {
retrofitManager = new RetrofitManager(context);
}
}
}
return retrofitManager;
}

public RetrofitService getRetrofitService() {
return retrofitService;
}

/**
* 初始化okhttp
*
* @param context
* @return
*/
private OkHttpClient initOkHttpClient(Context context) {
//新建一个文件用来缓存网络请求
File cacheDirectory = new File(context.getCacheDir().getAbsolutePath() + "responses");
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置连接超时
.readTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置从主机读信息超时
.writeTimeout(ServiceConfig.TIMEOUT, TimeUnit.SECONDS)//设置写信息超时
.retryOnConnectionFailure(true)///如果连接失败,尝试重连
.cache(new Cache(cacheDirectory, 10 * 1024 * 1024))//设置缓存文件
.addInterceptor(initInterceptor())//设置okhttp拦截器,这样做的好处是可以为你的每一个retrofit2的网络请求都增加相同的head头信息,而不用每一个请求都写头信息
.addInterceptor(initLogInterceptor())//打印日志
.build();
return okHttpClient;
}

/**
* 初始化http拦截器
*
* @return
*/
private Interceptor initInterceptor() {
BasicParamsInterceptor builder = new BasicParamsInterceptor.Builder()
// .addHeaderParam("Content-Type", "text/xml; charset=utf-8")// 对于SOAP 1.1, 如果是soap1.2 应是Content-Type: application/soap+xml; charset=utf-8
.build();
return builder;
}

/**
* 初始化日志信息
*
* @return
*/
private Interceptor initLogInterceptor() {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
Log.i("TTT", "请求参数:" + message);
}
});
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
return interceptor;
}

/***
* 初始化Retrofit
*/
private Retrofit initRetrofit(OkHttpClient client) {
Retrofit retrofit = new Retrofit.Builder()
.client(client)//设置 HTTP Client 用于请求的连接
// .addConverterFactory(SimpleXmlConverterFactory.create(serializer))//解析xml
.addConverterFactory(ScalarsConverterFactory.create())//如果网络访问返回的字符串,而不是json数据格式,要使用下面的转换器
.addConverterFactory(GsonConverterFactory.create())//如果网络访问返回的是json字符串,使用gson转换器
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//此处顺序不能和上面对调,否则不能同时兼容普通字符串和Json格式字符串 为了支持rxjava,需要添加下面这个把 Retrofit 转成RxJava可用的适配类
.baseUrl(ServiceConfig.BASE_URL)
.build();
return retrofit;
}

}接着是初步封装mvp层,已登入为例子:
我的目录结构,一个model对应一个presenter对应多个view



因为presenter都会接收到model返回来的结果,所以我将它单独写成了一个父类IPresenter:public interface IPresenter {
void success(int code, Object result);

void error(int code, String result);
}每个Presenter接口类都继承IPresenter:public interface IAccountPresenter extends IPresenter {
/**
* 登入
*
* @param userName
* @param password
*/
void login(String userName, String password); }一般写法是 rService.login(userName, password)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Object>() {
@Override
public void onSubscribe(Subscription s) {

}

@Override
public void onNext(Object o) {

}

@Override
public void onError(Throwable t) {

}

@Override
public void onComplete() {

}
});封装后写法: rService.login(userName, password)
.compose(new RxFlowableTransformer())
.subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.LOGIN_SUC));我的model实现类:/**
* 用户具体实现类
* Created by 1 on 2018/1/24.
*/

public class AccountModelImpl implements IAccountModel {
private RetrofitService rService;
private IPresenter basePresenter;

public AccountModelImpl(RetrofitManager retrofitManager, IPresenter basePresenter) {
rService = retrofitManager.getRetrofitService();
this.basePresenter = basePresenter;
}

@Override
public void login(String userName, String password) {
rService.login(userName, password)
.compose(new RxFlowableTransformer())
.subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.LOGIN_SUC));
}

@Override
public void register(AccountBean account) {
rService.register(account)
.compose(new RxFlowableTransformer())
.subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.REGISTER_SUC));
}

@Override
public void forgetPassword(AccountBean accountBean) {
rService.forgetPw(accountBean)
.compose(new RxFlowableTransformer())
.subscribe(new IRxSubscribler(basePresenter, HttpInterfaceCode.FORGET_PW_SUC));
}
}因为我将Ipresenter放到了 mode
9c98
l类中,所以结果直接回调到了presenter的实现类中success和error方法中;
RxFlowableTransformer类很简单,就是封装了线程而已:public final class RxFlowableTransformer implements FlowableTransformer {
@Override
public Publisher apply(Flowable upstream) {
return upstream.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread());
}

}接着看IRxSubscribler类,有两个参数,一个是iPresenter引用,还有一个是接口回调成功值(如值为20,则接口回调失败会返回-20);public class IRxSubscribler<T> extends RxSubscribler<T> {
private IPresenter basePresenter;
private int interfaceCode;

public IRxSubscribler(IPresenter basePresenter, int interfaceCode) {
this.basePresenter = basePresenter;
this.interfaceCode = interfaceCode;
}

@Override
public void success(Object o) {
basePresenter.success(interfaceCode, o);
}

@Override
public void error(String result) {
basePresenter.error(-interfaceCode, result);
}
}这里只是进行了回调操作,接着去RxSubscribler类public abstract class RxSubscribler<T> implements Subscriber<T> {
@Override
public final void onSubscribe(Subscription s) {
s.request(Long.MAX_VALUE);
}

@Override
public final void onNext(T o) {
checkIsSucc(o);
}

@Override
public final void onError(Throwable t) {

if (t instanceof SocketTimeoutException) {
error("服务器连接超时");
} else if (t instanceof ConnectException) {
error("服务器链接失败");
} else if (t instanceof TimeoutException) {
error("网络超时");
} else if (t instanceof UnknownHostException) {
error("未知主机错误");
} else {
error("未知错误");
t.printStackTrace();
}
}

@Override
public final void onComplete() {

}

public abstract void success(T o);

public abstract void error(String result);

private void checkIsSucc(T o) {
if (o instanceof BaseResponse) {
BaseResponse response = (BaseResponse) o;
String errorMessage = "未知错误";
switch (response.getCode()) {
case HttpInterfaceCode.NET_REUQEST_OK:
success(o);
return;
case HttpInterfaceCode.NET_REQUEST_ERROR:
errorMessage = "请求错误";
break;
case HttpInterfaceCode.NET_REQUEST_REJECT:
errorMessage = "请求被拒绝";
break;
case HttpInterfaceCode.NET_REQUEST_UNFOUND:
errorMessage = "请求未响应";
break;
case HttpInterfaceCode.NET_SERVICE_ERROR:
errorMessage = "服务器错误";
break;
case HttpInterfaceCode.NET_NUKNOWN_ERROR:
errorMessage = "未知错误";
break;
}
error(errorMessage);
}

}
}流程大概就是这样。源码会在以后发布到github上
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息