2022-01-25

蛙笑网络请求优化方案

优化目的

解耦网络请求,解决嵌套地狱,减少内存泄漏

方案对比

  • 原始请求方式:
HttpMethods.getInstance().getJsonData(new NoProgressSubscriber(
        new SubscriberOnNextListener<RespListBean<GiftItemBean>>() {
            @Override
            public void onNext(RespListBean<GiftItemBean> o) {
                if (null != o) {
                    if (0 == o.status) {
                        if (null != o.table) {
                            if (null != o.table.row && o.table.row.size() > 0) {
                                giftItemBeanList = new ArrayList<GiftItemBean>();
                                for (int i = 0; i < o.table.row.size(); i++) {
                                    giftItemBeanList.add(o.table.row.get(i));
                                }
                                selectExchangeAdp.getDate(giftItemBeanList);
                            }
                        } else {
                            ToastUtils.getInstance().ShowToast(context, "没有查询到兑换商品");
                        }
                    } else {
                        ToastUtils.getInstance().ShowToast(context, o.msg);
                    }
                } else {
                    ToastUtils.getInstance().ShowToast(context, "无法连到服务器。");
                }
            }
        }, new TypeToken<RespListBean<GiftItemBean>>() {
}.getType()), getGiftByIntegralExchangeBean);
  • 改造完成的请求方式

    HttpUtils
            .createApi(waxiaoApi.class)
            .getBanner()
            .compose(Transformer.<BaseData<List<BannerBean>>>switchSchedulers(loading_dialog))
            .subscribe(new DataObserver<List<BannerBean>>() {
                
                @Override
                protected boolean isHideToast() {
                    return false;
                }
    
                //tag下的一组或一个请求,用来处理一个页面的所以请求或者某个请求
                //设置一个tag就行就可以取消当前页面所有请求或者某个请求了
                @Override
                protected String setTag() {
                    return "tag1";
                }
    
                @Override
                protected void onError(String errorMsg) {
    
                }
    
                @Override
                protected void onSuccess(RespListBean<GiftItemBean> o) {
                  if ( o.table.row.size() > 0) {
                                    giftItemBeanList = new ArrayList<GiftItemBean>();
                                    for (int i = 0; i < o.table.row.size(); i++) {
                                        giftItemBeanList.add(o.table.row.get(i));
                                    }
                                    selectExchangeAdp.getDate(giftItemBeanList);
                  }
                }
            });
    

方案优势:

  • 清晰的结构:

    createApi(WanAndroidApi.class)不同的模块使用不同的service

    设置tag 取消网络请求,减少崩溃和内存泄漏

    loading_dialog可以继承ILoadingView 接口化处理 让进度条不止能使用dialog

方案的改造成本

  • rxjava1.x->rxjava2.x,涉及到api 的更改
  • 整理之前的网络请求,换成新的方式

方案的改造细节

createApi

 public <A> A createApi(String baseUrlKey, String baseUrlValue, Class<A> apiClass) {
            Retrofit retrofit = new RetrofitBuilder()
                    .setBaseUrl(baseUrlValue)
                    .setCallAdapterFactory(callAdapterFactory)
                    .setConverterFactory(converterFactory)
                    .setOkHttpClient(okHttpClient)
                    .build();

            api = retrofit.create(apiClass);

            apiServiceCache.put(key, api);
        return api;
    }

DataObserver

public abstract class DataObserver<T> extends BaseObserver<RespListBean<T>> {

    /**
     * 失败回调
     *
     * @param errorMsg 错误信息
     */
    protected abstract void onError(String errorMsg);

    /**
     * 成功回调
     *
     * @param data 结果
     */
    protected abstract void onSuccess(T data);

    @Override
    public void doOnSubscribe(Disposable d) {
    }

    @Override
    public void doOnError(String errorMsg) {
        if (!isHideToast() && !TextUtils.isEmpty(errorMsg)) {
            ToastUtils.showToast(errorMsg);
        }
        onError(errorMsg);
    }

    @Override
    public void doOnNext(RespListBean<T> data) {
        //可以根据需求对code统一处理
//        switch (data.getCode()) {
//            case 0:
//                onSuccess(data.getData());
//                break;
//            case ..:
//                onError(data.getMsg());
//                break;
//           
//        }
        //统一做异常处理
            if(data==null){
                 onError(" 无法连到服务器.");
                 return;
            }
           onSuccess(data.getData());
    }

    @Override
    public void doOnCompleted() {
    }


}

BaseObserver

public abstract class BaseObserver<T> implements Observer<T>, ISubscriber<T> {

    /**
     * 是否隐藏toast
     *
     * @return
     */
    protected boolean isHideToast() {
        return false;
    }

    /**
     * 标记网络请求的tag
     * tag下的一组或一个请求,用来处理一个页面的所以请求或者某个请求
     * 设置一个tag就行就可以取消当前页面所有请求或者某个请求了
     * @return string
     */
    protected String setTag(){
        return null;
    }

    @Override
    public void onSubscribe(@NonNull Disposable d) {
        RxHttpManager.get().add(setTag(), d);
        doOnSubscribe(d);
    }

    @Override
    public void onNext(@NonNull T t) {
        doOnNext(t);
    }

    @Override
    public void onError(@NonNull Throwable e) {
        String error = ApiException.handleException(e).getMessage();
        setError(error);
    }


    @Override
    public void onComplete() {
        doOnCompleted();
    }


    private void setError(String errorMsg) {
        doOnError(errorMsg);
    }

}

Log细节优化:

public class RxHttpLogger implements HttpLoggingInterceptor.Logger {
    private StringBuffer mMessage = new StringBuffer();

    @Override
    public void log(String message) {
        // 请求或者响应开始
        if (message.startsWith("--> POST")) {
            mMessage.setLength(0);
            mMessage.append(" ");
            mMessage.append("\r\n");
        }
        if (message.startsWith("--> GET")) {
            mMessage.setLength(0);
            mMessage.append(" ");
            mMessage.append("\r\n");
        }
        // 以{}或者[]形式的说明是响应结果的json数据,需要进行格式化
        if ((message.startsWith("{") && message.endsWith("}"))
                || (message.startsWith("[") && message.endsWith("]"))) {
            message = JsonUtil.formatJson(message);
        }
        mMessage.append(message.concat("\n"));
        // 请求或者响应结束,打印整条日志
        if (message.startsWith("<-- END HTTP")) {
            Log.e("RxHttpUtils", mMessage.toString());
        }
    }
}

线程切换辅助

public class Transformer {

    /**
     * 无参数
     *
     * @param <T> 泛型
     * @return 返回Observable
     */
    public static <T> ObservableTransformer<T, T> switchSchedulers() {
        return switchSchedulers(null);
    }

    /**
     * 带参数  显示loading对话框
     *
     * @param loadingView loading
     * @param <T>         泛型
     * @return 返回Observable
     */
    public static <T> ObservableTransformer<T, T> switchSchedulers(final ILoadingView loadingView) {
        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(@NonNull Observable<T> upstream) {
                return upstream
                        .subscribeOn(Schedulers.io())
                        .unsubscribeOn(Schedulers.io())
                        .doOnSubscribe(new Consumer<Disposable>() {
                            @Override
                            public void accept(@NonNull Disposable disposable) throws Exception {
                                if (loadingView != null) {
                                    loadingView.showLoadingView();
                                }
                            }
                        })
                        .subscribeOn(AndroidSchedulers.mainThread())
                        .observeOn(AndroidSchedulers.mainThread())
                        .doFinally(new Action() {
                            @Override
                            public void run() throws Exception {
                                if (loadingView != null) {
                                    loadingView.hideLoadingView();
                                }
                            }
                        });
            }
        };
    }

}

Api service 请求方式

 @POST("posapi/json")
    Observable<RespListBean<ListBean>> getItemData(ReqJsonBean bean)

拼装请求bean

val requestJsonBean  = ApiHelper.parseRequestBean(XXXRequestbean,funcName)

parseRequestBean核心代码

 Gson gson = new GsonBuilder()
                .setPrettyPrinting()
                .disableHtmlEscaping()
                .create();
        ReqJsonBean.RequestEntity requestEntity = new ReqJsonBean.RequestEntity();
        requestEntity.setRequest(xxxRequest);
        ReqJsonBean jsonBean = new ReqJsonBean();
        jsonBean.setRequestJson(gson.toJson(requestEntity).replaceAll("\\\\", ""));
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容