这是android的网络底层封装,可以简便的使用网络调用,对网络返回进行统一的封装处理。
先上代码,以登录为例
下面是使用代码
//先通过单例模式获取retrofit对象,调用api类访问接口。
Observable<HttpResult<TokenRec>> call = NetConnect.getInstance().getService(UserService.class).userLogin(vm.getUsername(),vm.getPassword());
call.compose(NetConnect.<HttpResult<TokenRec>>setThread()).subscribe(new CallBackObserver<TokenRec>() {
@Override
public void onSuccess(HttpResult<TokenRec> response) {
});
api接口
public interface UserService {
/**登录*/
@FormUrlEncoded //通过表单访问,参数field注解必须要有这个。
@POST("user/login") //url地址后缀
Observable<HttpResult<TokenRec>> userLogin(@Field("username") String username,@Field("password") String password);
}
网路请求类
public class NetConnect {
// 网络请求超时时间值(s)
private static final int DEFAULT_TIMEOUT = 60;
private static NetConnect instance;
private Retrofit retrofit;
//单例
public static NetConnect getInstance(){
if(instance == null){
instance = new NetConnect();
}
return instance;
}
public NetConnect(){
// 创建一个OkHttpClient
OkHttpClient.Builder builder =new OkHttpClient.Builder();
builder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
builder.readTimeout(DEFAULT_TIMEOUT,TimeUnit.SECONDS);
builder.writeTimeout(DEFAULT_TIMEOUT,TimeUnit.SECONDS);
//添加参数
builder.addInterceptor(new BaseParamsInterceptor());
// 打印参数
builder.addInterceptor(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
// 失败后尝试重新请求
builder.retryOnConnectionFailure(true);
retrofit = new Retrofit.Builder()
.baseUrl(AppConfig.baseUrl+"test/")
.client(builder.build())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())//rxjava支持
.addConverterFactory(GsonConverterFactory.create())//数据转json
.build();
}
//根据接口的字节码文件对象获取接口对象
public static <T> T getService(Class<T> clazz){
T service = NetConnect.getInstance().retrofit.create(clazz);
return service;
}
/**链式调度转换,请求回调转换线程*/
public static <T>ObservableTransformer<T,T> setThread(){
return new ObservableTransformer<T, T>() {
@Override
public ObservableSource<T> apply(Observable<T> upstream) {
return upstream.subscribeOn(Schedulers.io()).unsubscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
}
};
}
}
请求参数动态添加, 添加参数三种方式
public class BaseParamsInterceptor implements Interceptor{
@Override
public Response intercept(Chain chain) throws IOException {
Request oldRequest = chain.request();
Request newRequest = addParam(oldRequest);
return chain.proceed(newRequest);
}
/**添加参数*/
public Request addParam(Request oldRequest){
FormBody form= (FormBody) oldRequest.body();
String token = (String) SharePreferenceInfo.getInstance().getValue(BaseParam.token,SharePreferenceInfo.DataType.STRING);
String userId =(String) SharePreferenceInfo.getInstance().getValue(BaseParam.userId,SharePreferenceInfo.DataType.STRING);
if(token == null){
token ="";
}
if(userId == null){
userId="";
}
RequestBody newFormBody = new FormBody.Builder()
.add("token",token)
.add("userId",userId)
.build();
//默认添加formBody后不能添加新的form表单,需要先将RequestBody转成string去拼接
String postBodyString = bodyToString(oldRequest.body());
postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(newFormBody);
Request newRequest = oldRequest.newBuilder()
.method(oldRequest.method(),oldRequest.body())
.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), postBodyString))
.build();
return newRequest;
}
/**RequestBody转String的方法*/
private static String bodyToString(final RequestBody request){
try {
final RequestBody copy = request;
final Buffer buffer = new Buffer();
if(copy != null)
copy.writeTo(buffer);
else
return "";
return buffer.readUtf8();
}
catch (final IOException e) {
return "did not work";
}
}
}
请求回调
public abstract class CallBackObserver<T> implements Observer<HttpResult<T>> {
private Disposable d;
@Override
public void onSubscribe(Disposable d) {
this.d=d;
}
//数据处理
@Override
public void onNext(HttpResult<T> tHttpResult) {
//定义返回code=200表示成功
if(tHttpResult.getCode().equals(Constant.String_200)){
onSuccess(tHttpResult);
}else{
if(TextUtil.isEmpty(tHttpResult.getMsg())){
ToastUtil.show(R.string.error_unknow);
}else{
ToastUtil.show(tHttpResult.getMsg());
}
}
}
@Override//异常信息统一处理
public void onError(Throwable e) {
//中断请求
d.dispose();
//Http异常
if(e instanceof HttpException){
ToastUtil.show(((HttpException) e).code()+"");
}
//自定义的异常类,主要是接口返回不正确,无法自动转换
if (e instanceof ApiException) {
ToastUtil.show(((ApiException) e).getResult().toString());
}
//io异常
if (e instanceof IOException) {
ToastUtil.show(R.string.error_socket_timeout);
}
e.printStackTrace();
}
//请求完成
@Override
public void onComplete() {
d.dispose();
}
//抽象方法,给外部扩展结果处理
public abstract void onSuccess(HttpResult<T> response);
}
数据model
public class TokenRec {
private String token;
private String userId;
public String getToken() {
return token;
}
public String getUserId() {
return userId;
}
}
public class HttpResult<T> {
/** 错误码 */
private String code;
/**错误信息*/
private String msg;
/**返回消息主题*/
private T data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
数据格式为json,先对返回的数据code进行校验,如果是200,返回数据成功,然后才会进入onSuccess方法给用户处理,否则,由于封装了回调类直接处理掉。