Rxjava+retrofit共通要求パラメータおよび要求結果パッケージの追加


RxJava+Retrofit+okHttpは現在androidの主流のネットワーク要求フレームワークとして、自分のプロジェクトでの応用を書きます!本文の主な内容:1.使用するリクエストに共通のリクエストパラメータを追加します.2.自分のプロジェクトに適したサーバインタフェースデータ処理クラスをカプセル化する.
開発環境
retrofitVersion=‘2.2.0’ok 3 Version=‘3.6.0’rxjavaVersion=‘1.2.7’rxAndroid Version=‘1.2.1’rxlifecycleVersion=‘0.3.0’rxlifecycleVersionは、RxJavaにおけるsubscriptionによるメモリリークを防止するために誕生した.たとえば、参照するview(fragment,activity)が破棄されますが、rxjavaライフサイクルが終了していない場合、破棄されたview(fragment,activity)を再度呼び出すと異常が発生します.
  • はPostインタフェースのように形成されています.http://base/interface/xxx各インタフェースには、APPTOKEN(登録ユーザ登録状態)の戻り値が
  • である必要がある.
    {"erron":"100000","msg":"  "}//        
    {"data":{},"erron":"100000","msg":"  "}//          
    {"nowPage":"1","totalPage":"4","data":[],"erron":"100000","msg":"  "}//        

    まず、すべてのリクエストにデフォルトのapptokenフィールドを追加します.Okhttp 3のネットワークブロッカーInterceptorを使用します.コアコード:
    builder = new OkHttpClient.Builder();
            if (BuildConfig.DEBUG) {
                HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
                logging.setLevel(HttpLoggingInterceptor.Level.BODY);
                builder.addInterceptor(logging);
            }
            builder.connectTimeout(6 * 1000, TimeUnit.MILLISECONDS)//10s    
                    .readTimeout(10 * 1000, TimeUnit.MILLISECONDS)
                    .writeTimeout(10 * 1000, TimeUnit.MILLISECONDS);
            //  token   
            builder.addInterceptor(new TokenInterceptord());
            //         
            Interceptor netErrorInterceptor = new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    if (NetWorkUtil.isNetworkConnected())
                        return chain.proceed(chain.request());
                    else {
                        String res = "{\"erron\":\"-1200\",\"msg\":\"      \",\"nowPage\":\"0\",\"totalPage\":\"0\"}";
                        Response response = new Response.Builder()
                                .code(200)
                                .request(chain.request())
                                .protocol(Protocol.HTTP_1_1)
                                .addHeader("Cache-Control", "no-cache")
                                .addHeader("Content-Type", "text/html; charset=utf-8")
                                .body(RealResponseBody.create(MediaType.parse("text"), res.getBytes("utf-8")))
                                .build();
                        return response;
                    }
                }
            };
            builder.addNetworkInterceptor(netErrorInterceptor);

    上記の2つのネットワークブロッカーが追加され、apptokenを追加するブロッカーはアプリケーションブロッカー(Application Intercetor)、ネットワーク異常を追加するブロッカーはネットワークブロッカー(netErrorInterceptor)である.
    ネットワーク異常を追加するブロッキングの主な役割は、後続の結果セットをカプセル化する際にネットワーク異常を追加する必要がない場合です.
    apptokenパラメータ追加ブロッキングの詳細な実装:
    public class TokenInterceptord implements Interceptor {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            Request.Builder requestBuilder = request.newBuilder();
            if (canInjectIntoBody(request)) {
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
                formBodyBuilder.add("apptoken", SharedPreUtil.getAppToken());//    apptoken  
                RequestBody formBody = formBodyBuilder.build();
                String postBodyString = bodyToString(request.body());
                postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
                requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
            }
            request=requestBuilder.build();
            return chain.proceed(request);
        }
    
        private boolean canInjectIntoBody(Request request) {
            if (request == null) {
                return false;
            }
            if (!TextUtils.equals(request.method(), "POST")) {
                return false;
            }
            RequestBody body = request.body();
            if (body == null) {
                return false;
            }
            MediaType mediaType = body.contentType();
            if (mediaType == null) {
                return false;
            }
            if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded")) {
                return false;
            }
            return true;
        }
        private 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";
            }
        }
    }

    requestリクエストをブロックしてapptokenのpostフィールドを追加します.*次に3つの戻りタイプを解析し,一般的にappインタフェースはこの3つの場合に差が少ないはずである.1.第1種について:
    {"erron":"100000","msg":"成功"}//インタフェースは単純メッセージ情報を返す
    カスタム処理結果BaseBeanSubscribe
    public abstract class BaseBeanSubscribe<T extends BaseBean> extends Subscriber<T> {
        public enum ERROR_TYPE {
            DATA_EMPTY,//    
            DATA_ERROR,//      
            NET_ERROR,//      
            TOKEEN_ERROR,//apptoken     。
        }
    
        @Override
        public void onCompleted() {
        }
    
        @Override
        public void onError(Throwable e) {
            LogUtils.i("Zuzu", "ResultSubscriber-->exception");
            e.printStackTrace();
            if (NetWorkUtil.isNetworkConnected()) {
                onError(ERROR_TYPE.DATA_ERROR, "    !");
            } else {
                onError(ERROR_TYPE.NET_ERROR, "      ,         !");
            }
            LogUtils.i("Zuzu", "request fail!");
        }
    
        @Override
        public void onNext(T t) {
            if (t == null) {
                LogUtils.i("Zuzu", "data_empty!");
                onError(ERROR_TYPE.DATA_EMPTY, "     !");
            } else if ("100002".equals(t.getErron()) || "100003".equals(t.getErron())) {
                String msg;
                if ("-1".equals(SharedPreUtil.getAppToken())) {
                    msg = "      ,       !";
                } else {
                    msg = "        ,     !";
                }
                onError(ERROR_TYPE.TOKEEN_ERROR, msg);
            } else if ("100000".equals(t.getErron())) {
                sucess();
            } else if ("-1200".equals(t.getErron())) {
                onError(ERROR_TYPE.NET_ERROR, t.getMsg());
            } else {
                onError(ERROR_TYPE.DATA_ERROR, t.getMsg());
            }
        }
    
        //    
        protected abstract void sucess();
        //    !
        protected abstract void onError(ERROR_TYPE type, String msg);
    }
      basebean
    public class BaseBean<T> {
        private String erron;
        private String msg;
        private T data;
        ...set get  ...
    }

    このコードセグメントは、結果フィルタセットに基づいてエラーを処理する場合を実現する.ネットワーク異常は、上述したように処理されているため、ここでは直接ネットワーク異常を取得することができる.
    2 . 2つ目:
    {"data":{},"erron":"100000","msg":"成功"}//インタフェースは詳細フィールドを返します
    public abstract class ResultSubscriber<D, T extends BaseBean<D>> extends BaseBeanSubscribe<T> {
        @Override
        public void onNext(T t) {
            if (t != null && "100000".equals(t.getErron())) {
                onSuccess(t.getData());
                return;
            }
            super.onNext(t);
        }
    
        @Override
        protected void sucess() {
    
        }
    
        //    
        protected abstract void onSuccess(D data);
    }

    このように書くメリットは、onSuccessで返されるデータが「data」{}のデータであることです.3.最後のタイプ、ページング:
    {「nowPage」:“1”,“totalPage”:“4”,“data”:[],“erron”:“100000”,“msg”:“成功”}
    public abstract class PageListResultSubscriber<D, T extends BasePageBean<D>> extends ResultSubscriber<List<D>, T> {
        @Override
        public void onNext(T t) {
    
            if (t != null && "100000".equals(t.getErron())) {
                onSuccess(t.getData(), Integer.parseInt(t.getNowPage()), Integer.parseInt(t.getTotalPage()));
                return;
            }
            super.onNext(t);
        }
    
        protected abstract void onSuccess(List data, int nowPage, int totalPage);
    
        @Override
        protected void onSuccess(List data) {
            //   
        }

    onSucessでリストセットを返し、totalpage、nowpage*が最後に上記の準備を完了すると、コードの使用は簡単になりますeg:インタフェースがあります
    @POST(“admin/index/surnames”) @FormUrlEncoded Observable getBjxList(@Field(“id”) String id);
    mService.getBjxList("0")
                    .compose(getView().bindToLifecycle())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new ResultSubscriber,BjxListBean>() {
                        @Override
                        protected void onSuccess(List data) {
                            if(getView()!=null)
                            {
                                getView().showSucessUi(data);
                            }
                        }
    
                        @Override
                        protected void onError(ERROR_TYPE type, String msg) {
                            if(getView()!=null)
                            {
                                getView().showError(type,msg);
                            }
                        }
                    });
      BjxListBean
    public class BjxListBean extends BaseBean<List<BjxListBean.DataBean>> {
        public static class DataBean implements Serializable{
            private String id;
            private String xing;
    
            public String getId() {
                return id;
            }
    
            public void setId(String id) {
                this.id = id;
            }
    
            public String getXing() {
                return xing;
            }
    
            public void setXing(String xing) {
                this.xing = xing;
            }
        }
    }