retrofit2+okhttp3+rxjava网络封装
16lz
2021-01-26
这是android的网络底层封装,可以简便的使用网络调用,对网络返回进行统一的封装处理。
先上代码,以登录为例
下面是使用代码
//先通过单例模式获取retrofit对象,调用api类访问接口。 Observable> call = NetConnect.getInstance().getService(UserService.class).userLogin(vm.getUsername(),vm.getPassword()); call.compose(NetConnect.>setThread()).subscribe(new CallBackObserver() { @Override public void onSuccess(HttpResult response) { });
api接口
public interface UserService { /**登录*/ @FormUrlEncoded //通过表单访问,参数field注解必须要有这个。 @POST("user/login") //url地址后缀 Observable> 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 getService(Class clazz){ T service = NetConnect.getInstance().retrofit.create(clazz); return service; } /**链式调度转换,请求回调转换线程*/ public static ObservableTransformer setThread(){ return new ObservableTransformer() { @Override public ObservableSource apply(Observable 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 implements Observer> { private Disposable d; @Override public void onSubscribe(Disposable d) { this.d=d; } //数据处理 @Override public void onNext(HttpResult 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 response);}
数据model
public class TokenRec { private String token; private String userId; public String getToken() { return token; } public String getUserId() { return userId; }}
public class HttpResult { /** 错误码 */ 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方法给用户处理,否则,由于封装了回调类直接处理掉。
更多相关文章
- Android实现简单的城市列表功能
- 适合Material Dsign的新抽屉---Navigation View介绍
- Android(安卓)GreenDao最的基本配置与初始化
- Android(安卓)底部菜单栏(RadioGroup+Fragment)美化
- android studio ,gradle 导入项目 常见错误 错误提示:Error:(2, 0)
- Android(安卓)JNI 编程
- PreferenceActivity 参数设置UI的使用
- Android数据通信开发与应用(四):实战开发
- Android异步AsyncTask二三解