该封装中除了原有的功能,额外包含什么功能先说一下,另外先展示基本使用方式。看是不是你想要的 1、公共参数的添加 2、token的自动刷新 3、错误请求的自动处理 4、单例模式以及工程模式的retrofit,以适应出现不同域名请求的情况 使用方式如下 1、接口方法定义 2、调用方法 以上就是使用的方法,写这个的初衷是因为我懒,抱着磨刀不误砍柴工的想法,所以封装的尽可能简单。之后我会对该封装做非常细致的说明,每个类名称,和其中所负责的功能都会以文字描述,之后配上该类的整体代码。尽可能做到复制之后可以直接使用,也希望让你看了之后有所借鉴。(需要看的文字简述不多,代码复制可直接使用) 一、首先需要导入的库如下 二、类名“RetrofitUtil” , retrofit初始化,生产实例的工具类,一般初始化的过程类似,配置参数不同,代码中对配置的参数做详细说明 三、类名“OkHttpClientHelper” ,请求预处理,主要增加了公共参数的添加,以及请求链接的打印。这里代码做了判断分别进行参数添加,是因为请求以请求体方式和拼接方式请求时,添加参数方式有所不同。使用时记得将公共参数名和值改成自己需要的。 四、类名“RxHelper” , rxjava的帮助类,针对返回值做了统一处理,也对使用rxjava请求做了一些简化处理。token的刷新被注释掉了,如果需要token的自动刷新并从新请求原接口,注释的部分就很有必要看一下,里面注释很清楚。返回值的code判断请根据自己服务器返回的内容进行修改 五、接口名“ApiManage” ,请求接口,返回类型增加rxjava后改为Observable,@Query注解可以用于一般情况,请求参数直接拼接到请求地址上。 六、类名“NetCallback” ,统一的请求回调,这里用了抽象类作为回调接口,方便不进行实现失败的回调,因为失败的回调已经做了统一处理。使用时,在结果回调失败时如果有特殊逻辑,可以直接实现进行。 七、类名“BaseResponse”,返回结果的基础映射类,需要和你服务器返回的通常参数做对应,data的实例根据参数单独创建。该类的使用方式可参考顶部的接口方法定义。 八、类名“ErrorRequestProcess”,错误的统一处理类,根据服务器返回code进行打印的地方自根据服务器错误对应的内容改一下 到此就结束了,这是第二次心血来潮写了篇博客。nnd还挺累,我看见别人有贴上自己的收款码的,不知道我…… 那我就不客气了,抱拳感谢
/** * 示例 * 上传名字 * <BaseResponse<Object>> BaseResponse为封装的公共请求结果实体,Object可以改成对应自己想要的实体 */ @POST("*********") Observable<BaseResponse<Object>> uploadName(@Query("name") String name);
RxHelper.deploy(RetrofitUtil.getRetrofit().uploadName("小明"), new NetCallback<StudentInfo>() { @Override public void onCompleted(StudentInfo studentInfo) { //StudentInfo studentInfo 这个要和 方法定义中的BaseResponse的泛型<studentInfo>保持一致 } });
implementation 'com.squareup.retrofit2:retrofit:2.1.0' implementation 'com.squareup.retrofit2:adapter-rxjava:2.1.0' implementation 'com.squareup.retrofit2:converter-gson:2.1.0' implementation 'com.squareup.okhttp3:logging-interceptor:3.8.0' implementation 'io.reactivex:rxjava:1.0.14' implementation 'io.reactivex:rxandroid:1.0.1'
public class RetrofitUtil { private static ApiManage api; /** * 一般调用方式,用于服务器域名相同的情况 */ public static ApiManage getRetrofit() { if(api==null){ Gson gson=new GsonBuilder() .serializeNulls() .setLenient() .create(); api = new Retrofit.Builder() .baseUrl(Api.BASE_URL) //服务器域名 Api,就是存放通用域名的接口,也可以是静态类,自己写一个,或者直接把地址些里面也可 .client(OkHttpClientHelper.getInstance().getOkHttpClient()) //请求预处理 .addConverterFactory(GsonConverterFactory.create(gson)) //gson自动解析配置 .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) //使用Rxjava自定义adapter,通常用法 .build().create(ApiManage.class); //发起请求的接口 } return api; } /** * 用于服务器域名不同的情况,传入服务器域名 */ public static ApiManage createRetrofitFrom(String baseUrl) { if (baseUrl == null) { baseUrl = Api.BASE_URL; } Gson gson=new GsonBuilder() .serializeNulls() .setLenient() .create(); ApiManage api = new Retrofit.Builder() .baseUrl(baseUrl) .client(OkHttpClientHelper.getInstance().getOkHttpClient()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create(gson)) .build().create(ApiManage.class); return api; } }
public class OkHttpClientHelper { private OkHttpClient mOkHttpClient; private static final int TIME_OUT_LIMIT = 60 * 1000;//超时时间 /** * 获取OkHttpClient * @return */ public OkHttpClient getOkHttpClient() { if (mOkHttpClient == null) { OkHttpClient.Builder builder = new OkHttpClient.Builder() //设置超时时间 .connectTimeout(TIME_OUT_LIMIT, TimeUnit.MILLISECONDS) .readTimeout(TIME_OUT_LIMIT, TimeUnit.MILLISECONDS) .writeTimeout(TIME_OUT_LIMIT, TimeUnit.MILLISECONDS) .retryOnConnectionFailure(true);//错误重连开启 //添加公共参数 builder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); if ("POST".equals(request.method())||"GET".equals(request.method())) { if (request.body() instanceof FormBody) { FormBody.Builder bodyBuilder = new FormBody.Builder(); FormBody formBody = (FormBody) request.body(); // 先复制原来的参数 for (int i = 0; i < formBody.size(); i++) { bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i)); } formBody = bodyBuilder .addEncoded("公共参数名", "公共参数值") .addEncoded("公共参数名", "公共参数值") .build(); request = request.newBuilder().post(formBody).build(); }else { HttpUrl httpUrl = request.url() .newBuilder() .addQueryParameter("公共参数名","公共参数值") .build(); request = request.newBuilder().url(httpUrl).build(); } } return chain.proceed(request); } }); //添加拦截打印请求日志 HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { Log.i("http-request", message); } }); interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(interceptor); mOkHttpClient = builder.build(); } return mOkHttpClient; } private OkHttpClientHelper() { } public static OkHttpClientHelper getInstance() { return LazyHolder.INSTANCE; } private static final class LazyHolder { private static final OkHttpClientHelper INSTANCE = new OkHttpClientHelper(); } }
public class RxHelper { private static int refreshTokenNumber = 0; private static Observable threadControl(Observable observable) { return observable //线程转换的常用方式,封装节约调用步骤 .observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.io()); } private static Subscription subscribe(final Observable observable, final NetCallback callback) { return observable .subscribe(new Subscriber<BaseResponse>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { callback.onFailed("系统错误,请联系管理员"); ErrorRequestProcess.throwableErrorRequest(e); } @Override public void onNext(BaseResponse baseResponse) { if (null != baseResponse) { if (baseResponse.getCode() == 503) { //判断token过期,重新获取token,并发起原请求 refreshToken(observable, callback); //自定义刷新token方法 return; } if (baseResponse.getCode() == 200) { //请求成功返回请求结果 callback.onCompleted(baseResponse.getData()); } else { callback.onFailed(baseResponse.getMsg()); ErrorRequestProcess.codeErrorRequest(baseResponse.getCode()); } } else { callback.onFailed("返回格式错误"); ErrorRequestProcess.codeErrorRequest(0); } } }); } /** * token刷新,该方法根据需要自行配置,如果请求中不需要刷新直接打印token过期就好 * @param observable * @param callback */ private static void refreshToken(final Observable observable, final NetCallback callback) { ToastUtil.showshortToastInButtom(MyApplication.getContext(),"token过期"); // if (refreshTokenNumber > 100) {//针对token的非过期错误的极端措施/因为过期没有单独的返回值 // Toast.makeText(MyApplication.getContext(), "token出现未知错误", Toast.LENGTH_LONG).show(); // refreshTokenNumber = 80; // return; // } // refreshTokenNumber++; // // Log.e("<请求错误log>", "CodeError=====: token验证失效,重新获取"); // //刷新token请求的参数预处理,这里根据你的刷新token接口替换 // String dateTime = String.valueOf(System.currentTimeMillis()); // StringBuilder stringBuilder = new StringBuilder(); // stringBuilder.append(Constants.appKey).append(dateTime).append(Constants.appSecret); // String sign = MD5.md5(stringBuilder.toString()); // //刷新token请求,换成你直接的请求,请求写在ApiManage中 // deploy(RetrofitUtil.getRetrofit().auth(Constants.appKey, dateTime, sign), new NetCallback<String>() { // @Override // public void onCompleted(String s) { // new SharedPreferencesHelper().put("token", s); //这里存储token并全局化,一般是在公共参数出添加 // deploy(observable, callback); //这里固定的调用旧的接口就好,记得本地token的更新处理 // } // }); } /** * 接口请求并返回结果 * @param observable 接口方法 * @param callback 请求结果的接口回调 * @return */ public static Subscription deploy(Observable observable, final NetCallback callback) { Subscription mSubscription = subscribe(threadControl(observable), callback); return mSubscription; } }
public interface ApiManage { /** * 这只是一个实例 */ @POST("这里是你自己请求的地址") //post是请求方式 Observable<BaseResponse<你自己的返回的实体类>> uploadName(@Query("你自己的参数名") String 参数名,@Query("你自己的参数名") String 参数名); }
public abstract class NetCallback<T> { /** * 完成 * @param t */ public abstract void onCompleted(T t); /** * 失败 * @param errMsg */ public void onFailed(String errMsg) { } }
public class BaseResponse<T> { private int code; private String msg; private T data; public int getCode() { return code; } public void setCode(int 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; } }
public class ErrorRequestProcess { public static void throwableErrorRequest(Throwable e) { String errorMsg = "未知错误"; if (e instanceof UnknownHostException) { errorMsg = "网络不可用"; } else if (e instanceof SocketTimeoutException) { errorMsg = "请求网络超时"; } else if (e instanceof HttpException) { HttpException httpException = (HttpException) e; errorMsg = convertStatusCode(httpException); } else if (e instanceof ParseException || e instanceof JSONException || e instanceof JSONException) { errorMsg = "数据解析错误"; } logThrowableError(errorMsg); } private static String convertStatusCode(HttpException httpException) { String msg; if (httpException.code() >= 500 && httpException.code() < 600) { msg = "服务器处理请求出错"; } else if (httpException.code() >= 400 && httpException.code() < 500) { msg = "服务器无法处理请求"; } else if (httpException.code() >= 300 && httpException.code() < 400) { msg = "请求被重定向到其他页面"; } else { msg = "↑↑↑错误信息↑↑↑"; logThrowableError("未知错误",httpException.message()); } return msg; } /** * 这里是服务器返回的code,根据服务器的规定自行打印错误日志 * @param errorCode */ public static void codeErrorRequest(int errorCode) { switch (errorCode) { case -1: logCodeError("未知错误"); return; case 400: logCodeError("参数错误"); return; } logCodeError("未知错误"+errorCode); } public static void logCodeError(String error) { Log.e("<请求错误log>", "CodeError=====: " + error); Toast.makeText(MyApplication.getContext(),error,Toast.LENGTH_SHORT).show(); } public static void logThrowableError(String error) { Log.e("<请求错误log>", "ThrowableError=====: " + error); Toast.makeText(MyApplication.getContext(),error,Toast.LENGTH_SHORT).show(); } public static void logThrowableError(String error,String errorLog) { Log.e("<请求错误log>", "ThrowableError=====: " + errorLog); Toast.makeText(MyApplication.getContext(),error,Toast.LENGTH_SHORT).show(); } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算