retrofit interceptor body 加密_Android我的Retrofit+Rxjava封装,不搞花里胡俏

本文详细介绍了一套基于RxJava和Retrofit的网络请求库的使用方法,包括初始化配置、请求取消、错误处理等核心功能,并提供了丰富的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击上方“秦子帅”,选择“星标”

08:50 在看 

来源:jlanglanghttps://juejin.im/post/5d8ca1ef6fb9a04e20416472

前言

从我最开始用rx和retrofit.到现在,快3年了,这个库的内容,算是沉淀下来的东西,个人用这个做过的项目也有很多个了.和项目中用的有点区别,因为不能随便重构的原因,比项目里的更好.哈哈.

目录

e698db0c0c6c9edfa56a33c22d1f44ab.png

初始化

NetWorkManager.init(String baseUrl, Application context)

难点1 BaseBean:

作为一个库,这个类是一个头疼的问题.因为强耦合.我们一般写的baseBaen都是这样的:不同的人,有不同的协议,字段名会不一样,如果用这样的,明显是不行的.

class BaseBean{  String code;  T data;  String msg;}

不同的人,有不同的协议,字段名会不一样,如果用这样的,明显是不行的.

这个库是这样的(ParseInfo):

你只需要定义自己的basebean规则,即可

d7f750d881323b8ea592db24cb36d8f9.png

NetWorkManager.addParseInfo(                new RxParseInfo("code", "data", "msg", "200") //200代表成功时的code.        );

这里传入的参数都是key的名字.目前支持3个key值.我觉得基本够用了.codeKey判断成功dataKey返回数据msgKey服务器返回消息

详解

1.库是如何判定接口请求成功的

ParseInfo 里默认通过判断successCode与返回的codeKey的值进行比较的

public boolean isSuccess(JsonObject asJsonObject) {        if (checkSuccess != null) {            return checkSuccess.isSuccess(asJsonObject);        }        String code = asJsonObject.get(codeKey).toString();        return TextUtils.equals(code, successCode);    }

也可以自定义判断是否请求成功ParseInfo使用setCheckSuccess().非必须.主要是为了扩展.

new ParseInfo("code", "data", "msg", "200")
 .setCheckSuccess(new ParseInfo.CheckSuccess() {@Overridepublic boolean isSuccess(JsonObject asJsonObject) {return false;
                    }
                })

2.请求

public interface JApi {/**
     * 上传文件
      */@POST@Multipart
    Observable post(@Url String url, @PartMap HashMap params);/**
     * 通用POST
     *
     */@POST
    Observable post(@Url String url, @Body String json);/**
     * 通用POST
     */@POST
    Observable post(@Url String url, @Body SimpleParams json);/**
     * 通用get
     */@GET
    Observable get(@Url String url, @QueryMap SimpleParams params);
}

这里写了4个通用的retrofit的请求.我个人觉得是可以满足大部分的需求了.

如果满足不了.就写点定制的就好了.有人会觉得这么写不行,实际上,我就用这个已经写了很多项目了.

有人会问,为什么这里都是Observable,往后面看就知道了.嘿嘿

3.RetrofitUtil

这里使用了饿汉式懒加载单例.

public class RetrofitUtil {/**
     * 服务器地址
     */private static String API_HOST;private static Application mContext;private static final HashMap apis = new HashMap<>();@SuppressWarnings("unchecked")public static T getApi(Class c) {
        Object o = apis.get(c);if (null == o) {
            o = getInstance().create(c);
            apis.put(c, o);
        }return (T) o;
    }public static synchronized void init(String baseUrl, Application context) {if (TextUtils.isEmpty(baseUrl)) {return;
        }
        mContext = context;
        API_HOST = baseUrl;
        Instance.retrofit = Instance.getRetrofit();
        apis.clear();
    }public static Retrofit getInstance() {return Instance.retrofit;
    }private static class Instance {private static Retrofit retrofit = getRetrofit();private static Retrofit getRetrofit() {
            OkHttpClient.Builder client = new OkHttpClient.Builder()//拦截并设置缓存
                    .addNetworkInterceptor(new CacheInterceptor())//拦截并设置缓存
                    .addInterceptor(new CacheInterceptor())
                    .cache(new Cache(mContext.getCacheDir(), 10240 * 1024));// 设置代理if (NetWorkManager.getProxy() != null) {
                client.proxy(NetWorkManager.getProxy());
            }for (Interceptor i : NetWorkManager.mInterceptors) {
                client.addInterceptor(i);
            }if (BuildConfig.DEBUG) {
                HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
                interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
                client.addInterceptor(interceptor);
            }return new Retrofit.Builder()
                    .client(client.build())
                    .baseUrl(API_HOST)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
        }
    }

可以设置缓存,添加代理,重置baseurl

对Retrofit.create创建的实体类,进行了缓存.

4.实例

Disposable login = RetrofitUtil.getApi(JApi.class)
                .get("/login", SimpleParams.create()
                        .putP("key1", 1)
                        .putP("key2", 2)
                        .putP("key3", 2)
                        .putP("key4", 3)
                )
                .compose(JRxCompose.normal())
                .subscribe(new Consumer<String>() {@Overridepublic void accept(String s) throws Exception {
                    }
                });

一个简单的请求就是这样的.有人看了会问, JRxCompose是啥?先来张目录图

e1568c53674cd27cefb66f4c3317a79a.png

再来张代码

66d83da2aaa5e2ca7b63042edd367b34.png

这里为什么要写JsonArrayParesTransformerJsonParesTransformer.

因为在组件化的时候,跨组件GSON解析时,泛型是会丢失的.我不知道现在解决没.

所以使用这两个来统一解析结果.

如果你细心就会发现.JApi的方法,的返回参数都是Observable

也就是统一先用String接收结果,然后再解析成最终结果.

5.取消网络请求如何舒服的取消请求回调一直是个头疼的问题不取消就会内存泄露,调用已关闭的activity,造成崩溃.当然,现在有RxLifecyle之类的库,很方便.这里我简单实现了一个.不过有版本限制.依赖Android自带的Lifecycle

JApiImpl

public class JApiImpl implements JApi, LifecycleObserver, ObservableTransformer<String, String> {public static JApi getApi() {return RetrofitUtil.getApi(JApi.class);
    }public static JApiImpl with(Lifecycle lifecycle) {
        JApiImpl JApiImpl = new JApiImpl();
        lifecycle.addObserver(JApiImpl);return JApiImpl;
    }public static JApiImpl with(Fragment fragment) {return with(fragment.getLifecycle());
    }public static JApiImpl with(AppCompatActivity activity) {return with(activity.getLifecycle());
    }private Disposable disposable;@Overridepublic ObservableSource<String> apply(Observable<String> upstream) {return upstream.doOnSubscribe(disposable -> this.disposable = disposable);
    }private void cancel() {if (this.disposable != null && !disposable.isDisposed()) {
            disposable.dispose();
        }
    }@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)public void onDestroy() {this.cancel();
        Log.i("233", "取消了请求");
    }@Overridepublic Observable<String> post(String url, HashMap<String, RequestBody> params) {return getApi().post(url, params).compose(this);
    }@Overridepublic Observable<String> post(String url, String json) {return getApi().post(url, json).compose(this);
    }@Overridepublic Observable<String> post(String url, SimpleParams params) {return getApi().post(url, params).compose(this);
    }@Overridepublic Observable<String> get(String url, SimpleParams params) {return getApi().post(url, params).compose(this);
    }
}

实现了JApi,LifecycleObserver,ObservableTransformer

LifecycleObserver是为了利用现在android自带的Lifecycle实现取消回调

ObservableTransformer是为了转换Observer.拿到Disposable.

这么改一下后.请求就可以这样:

JApiImpl.with(this).get("/login", SimpleParams.create()
                        .putP("key1", 1)
                        .putP("key2", 2)
                        .putP("key3", 2)
                        .putP("key4", 3)
                ).compose(JRxCompose.normal()).subscribe(new Consumer() {@Override
                    public void accept(String s) throws Exception {
                    }
                });

6.添加加密/解密

NetWorkManager.initKey("私钥", "公钥");//加密解密

7.设置超时时间

NetWorkManager.setDefaultTimeOut(20);//秒

8.设置重试次数

NetWorkManager.setDefaultRetry(5);//重试次数

9.设置全局异常统一回调

NetWorkManager.setExceptionListener(new onExceptionListener() {@Overridepublic String onError(Throwable throwable) {return null;
            }
        });

10.设置添加全局code状态处理

NetWorkManager.setApiCallBack(new APICallBack() {@Overridepublic String callback(String code, String resultData) {
                JsonElement jsonElement = JSONFactory.parseJson(resultData);return JSONFactory.getValue(jsonElement, "message");
            }
        });

11.设置打开服务器返回msg异常

如果callback不处理,并打开isOpenApiException,则抛出服务器返回msg信息

NetWorkManager.setOpenApiException(true);

12.异常处理逻辑

String errorMsg = null;//通过code获取注册的接口回调.
    APICallBack apiCallback = NetWorkManager.getApiCallback();if (apiCallback != null) {String callbackMsg = apiCallback.callback(code, response);if (!TextUtils.isEmpty(callbackMsg)) {
            errorMsg = callbackMsg;
        }
    }//如果callback不处理,并打开isOpenApiException,则抛出服务器返回msg信息if (TextUtils.isEmpty(errorMsg) && NetWorkManager.isOpenApiException()) {
        errorMsg = msg;
    }//抛出异常,走到onError.throw new APIException(code, errorMsg);

13.解析结果是Object或Array的例子:

//结果是一个ObjectJApiImpl.with(this).post("/Login", SimpleParams.create()).compose(JRxCompose.obj(Login.class)).subscribe(new Consumer() {@Override
                    public void accept(Login login) throws Exception {
                    }
                });//结果是集合JApiImpl.with(this).post("/Login", SimpleParams.create()).compose(JRxCompose.array(Login.class)).subscribe(new Consumer>() {@Override
                    public void accept(List logins) throws Exception {
                    }
                });

14.简单的Observer这里支持传入CompositeDisposable,添加当前的Disposable,用于取消回调,如果你用了上面的JApiImpl,那么这里可以不传CompositeDisposable,这个是我最早实现统一取消回调的逻辑.

/**
 * @author jlanglang 2016/11/14 17:32
 * @版本 2.0
 * @Change
 */public abstract class SimpleObserver<T> implements Observer<T> {protected Disposable mDisposable;private CompositeDisposable mCompositeDisposable;public SimpleObserver() {this(null);
    }public SimpleObserver(CompositeDisposable compositeDisposable) {
        mCompositeDisposable = compositeDisposable;
    }@Overridepublic void onSubscribe(@NonNull Disposable d) {
        mDisposable = d;try {
            mCompositeDisposable.add(d);
        } catch (Exception ignored) {
        }
    }@Overridepublic void onNext(T t) {
        call(t);
    }@Overridepublic void onError(Throwable e) {
    }@Overridepublic void onComplete() {
    }public abstract void call(@NonNull T t);
}

15.ToastObserver

在实际使用的时候,我们一般不会每个请求都弹Toast. 所以.如果需要默认弹Toast的请求.可以使用这个类.

/**
 * @author jlanglang 2016/11/14 17:32
 */public abstract class ToastObserver<T> extends SimpleObserver<T> {public ToastObserver() {this(null);
    }public ToastObserver(CompositeDisposable com) {super(com);
    }@Overridepublic void onError(Throwable e) {
        String errorMsg = NetWorkErrorFactory.disposeError(e);if (!TextUtils.isEmpty(errorMsg)) {
            Toast.makeText(NetWorkManager.getContext(), errorMsg, Toast.LENGTH_SHORT).show();
        }
    }
}

16.异常解析工厂

这个类,其实让我很纠结,因为这个类好像没什么作用.又好像又作用. 但是太绕了. 比如在NetWorkTransformer中抛出的APIException,以及初始化设置的onExceptionListener都是这里来处理的. 但不调用这个方法.这个方法就无意义.

我是在上面的ToastObserver中调用了这个方法. 你可以自定义这个方法在哪调用.

/**
     * 异常时处理工厂
     *
     * @param throwable 异常
     * @return 获取异常提示消息
     */public static String disposeError(Throwable throwable) {
        Class extends Throwable> throwableClass = throwable.getClass();//处理Api自定义异常处理,请求是成功的,如果需要特殊处理,使用APICallBackif (throwableClass.equals(APIException.class)) {return throwable.getMessage();
        }//处理error异常,http异常
        onExceptionListener exceptionListener = NetWorkManager.getExceptionListener();if (exceptionListener != null) {return exceptionListener.onError(throwable);
        }return "";
    }

17.结语

大致使用就这些了,库里还包含了rxbus,欢迎大家点赞,留言提建议

源码地址:
https://github.com/Jlanglang/JRxRetrofit

—————END—————

81a47663398eee0bb0e9e13a4308ccfd.png     

 
 创作不易,点个“
在看c32b6c4d88133164d4990358abef4f62.gif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值