AndroidのOkhttpのパッケージ

20054 ワード

最近はネットリクエストが必要で、Okhttpという強力なライブラリを使って、小さなブログを書いてメモを取って、Okhttp 3と前のバージョンの違いを見てみましょう.
1.Okhttp 3とOkHttpの比較
  • OkHttpClientの作成方法が異なる
  • 例:
    OkHttpClient.Builder okHttpClientBuilder = client.newBuilder(); 
            /*      */  
            okHttpClientBuilder.connectTimeout(10, TimeUnit.SECONDS) 
                                .writeTimeout(30, TimeUnit.SECONDS) 
                                .readTimeout(30, TimeUnit.SECONDS);
    OkHttpClient mOkHttpClient = okHttpClientBuilder.build();
    

    okhttpは直接newOkHttpClientを提供し、okhttp 3にはBuilderが提供されており、作成者の設計モードをよく使用するには以下のパラメータがあります.
    Dispatcher dispatcher; //   
    Proxy proxy; //   
    List protocols;
    List connectionSpecs;
    final List interceptors = new ArrayList<>(); //     final List networkInterceptors = new ArrayList<>(); //       ProxySelector proxySelector;
    CookieJar cookieJar;
    Cache cache; //   
    InternalCache internalCache;
    SocketFactory socketFactory;
    SSLSocketFactory sslSocketFactory;
    HostnameVerifier hostnameVerifier;
    CertificatePinner certificatePinner;
    Authenticator proxyAuthenticator; //     
    Authenticator authenticator; //   
    ConnectionPool connectionPool;
    Dns dns; // DNS
    boolean followSslRedirects;
    boolean followRedirects;
    boolean retryOnConnectionFailure;
    int connectTimeout;
    int readTimeout;
    int writeTimeout;
    
  • クッキーの設定方法が異なります:
  • OkhttpはOkHttpClientのsetCookieHandlerメソッドを呼び出し、CookieHandlerはAndroid SDKが提供する注釈のcookie管理、CookieHandlerのようなCookieManagerはcookieの具体的な管理メソッドを実現し、CookieManagerを構築するにはCookieStoreインタフェースを実現する必要があり、システムはデフォルトの実装CookieStoreImplを提供し、cookieをメモリに格納するだけを担当している.
  • postメッセージボディ構築方式が異なる
  • OkhttpはMultipartBuilder,FormEncodingBuilderを用いてpostメッセージ体を構築し,最終的に構築されたのはRequestBodyであるが,okhttp 3はRequestBodyのサブクラスを追加し,コンストラクタはRequestBodyのサブクラスに配置する,MultipartBody.Builderはフォームデータを追加することも、ファイルなどのバイナリデータを追加することもできます
  • CallとCallbackが異なる
  • OK http 3の前にCookieHandlerでクッキーを管理する
    /* cookie   */ 
     mCookieHandler = new CookieManager(null, CookiePolicy.ACCEPT_ALL); 
     mOkHttpClient.setCookieHandler(mCookieHandler);
    

    3.0以降、2つのクラスCookiejar、Cookieの2つのクラスが追加され、インタフェースがオープンし、ユーザー自身がcookieの管理を実現する必要があります.CookieJarでは、以下のように簡単にCookieの管理を設定できます.
    okHttpClientBuilder.cookieJar(new CookieJar() {
           private final HashMap> cookieStore = new HashMap<>();
                 @Override
                   public void saveFromResponse(HttpUrl url, List cookies) {
                     cookieStore.put(url, cookies);
                    }
    
                @Override
                  public List loadForRequest(HttpUrl url) {
                       List cookies = cookieStore.get(url);
                       return cookies != null ? cookies : new ArrayList();
                }
        });
    
  • OkHttpClientのCancelメソッド
  • を削除
    3.0 callを外す前にmOkHttpClientを直接使用することができます.cancel(tag);3.0その後、この方法を直接去勢するには、次の方法を使用します.
     public void cancelCallsWithTag(Object tag) {
            checkInit();
    
            if (tag == null) {
                return;
            }
    
            synchronized (mOkHttpClient.dispatcher().getClass()) {
                for (Call call : mOkHttpClient.dispatcher().queuedCalls()) {
                    if (tag.equals(call.request().tag())) call.cancel();
                }
    
                for (Call call : mOkHttpClient.dispatcher().runningCalls()) {
                    if (tag.equals(call.request().tag())) call.cancel();
                }
            }
        }
    

    2.Okhttpパラメータの構成
    public class Params {
        public static final String METHOD_GET = "get";
        public static final String METHOD_POST = "post";
        //3           file head
        private HashMap urlParams = new HashMap<>();
        private HashMap fileParams = new HashMap<>();
        private HashMap headers = new HashMap<>();
    
        private String api = "";
        private String baseUrl = "";
        private String method;
    
        public Params() {
            urlParams = new HashMap();
            fileParams = new HashMap();
            headers = new HashMap();
            setBaseUrl(Constants.me().getHost());
    
            //       
            headers.put("Accept", "application/json");
            headers.put("Version", Constants.me().getVersionName());
            headers.put("Gis-Lat", String.valueOf(Constants.me().getLatitude()));
            headers.put("Gis-Lng", String.valueOf(Constants.me().getLongitude()));
    
            String token = Constants.me().getToken();
            if (!TextUtils.isEmpty(token)) {
                headers.put("Authorization", "Bearer " + token);
            }
            setMethod(METHOD_POST);
        }
    
        public String getMethod() {
            return method;
        }
    
        public void setMethod(String method) {
            this.method = method;
        }
    
        public String getApi() {
            return api;
        }
    
        public void setApi(String api) {
            this.api = api;
        }
    
        public String getUrl() {
            return baseUrl + api;
        }
    
        public String getBaseUrl() {
            return baseUrl;
        }
    
        public void setBaseUrl(String baseUrl) {
            this.baseUrl = baseUrl;
        }
    
    
    
        public void put(String key, Object value) {
            if (key != null) {
                urlParams.put(key, value);
            }
        }
        public void put(String key, String value) {
            if (key != null) {
                urlParams.put(key, value);
            }
        }
    
        public void put(String key, int value) {
            if (key != null) {
                urlParams.put(key, String.valueOf(value));
            }
        }
    
        public void put(String key, double value) {
            if (key != null) {
                urlParams.put(key, String.valueOf(value));
            }
        }
        public void put(String key, float value) {
            if (key != null) {
                urlParams.put(key, String.valueOf(value));
            }
        }
    
        public void putHeaders(final String key, final int value) {
            this.putHeaders(key, String.valueOf(value));
        }
    
        public void putHeaders(final String key, final String value) {
            headers.put(key, value);
        }
    
        /**
         * @param key
         * @param file
         */
        public void put(String key, File file) {
            if (file != null && file.exists()) {
                fileParams.put(key, file);
            }
        }
        //     
        public boolean isMultipart() {
            return !fileParams.isEmpty();
        }
    
    
        public HashMap getUrlParams() {
            return urlParams;
        }
    
        public HashMap getFileParams() {
            return fileParams;
        }
    
        public HashMap getHeaders() {
            return headers;
        }
    
        @Override
        public String toString() {
            return urlParams.toString();
        }
    }
    
    

    3.Okhttpのパッケージ
    final public class HttpKit {
        private static final int DEFAULT_MILLISECONDS = 60000; //       
    
        private OkHttpClient.Builder okHttpClientBuilder;
        private OkHttpClient okHttpClient;
        private Handler mDelivery;
        private Context mContext;
        private final List handlers = new ArrayList<>();//       
        private PersistentCookieStore cookieStore;//     cookie
    
        public interface HttpCallback {
            //       ,       
            public void onStarted(Request request);
            //         ,       
            public void onProgressChanged(float progress, long total);
    
            /**
             * response    
             *
             * @param response
             * @return
             */
            @Deprecated
            public boolean validateReponse(Response response);
            //    ,     ,          callback ,   
            public T parseNetworkResponse(Response response) throws ApiException;
            //    ,     
            public void onError(ApiException e);
            //    
            public abstract void onResponse(T response);
        }
    
        private static final HttpKit me = new HttpKit();
    
    
        private HttpKit() {
            okHttpClientBuilder = new OkHttpClient.Builder();
            okHttpClientBuilder.connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
            okHttpClientBuilder.readTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
            okHttpClientBuilder.writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS);
    
            mDelivery = new Handler(Looper.getMainLooper());
        }
    
        public static HttpKit me() {
            return me;
        }
    
        //     cookie   ,  
        public static HttpKit init(Context context) {
            me().setContext(context);
            return me();
        }
    
        private void setContext(Context context) {
            this.mContext = context;
            cookieStore = new PersistentCookieStore(mContext);//     cookie
            CookieJarImpl cookieJar = new CookieJarImpl(cookieStore);
            okHttpClientBuilder.cookieJar(cookieJar);
        }
        //  cookie
        public void setCookie(Uri uri, Cookie cookie) {
            HttpUrl httpUrl = new HttpUrl.Builder().scheme(uri.getScheme()).host(uri.getHost()).build();
            cookieStore.add(httpUrl, cookie);
        }
    
        public void removeAllCookie() {
            cookieStore.removeAll();
        }
    
        //     
        public HttpKit addInterceptor(Interceptor interceptor) {
            okHttpClientBuilder.addInterceptor(interceptor);
            return this;
        }
        //     
        public HttpKit addNetworkInterceptor(Interceptor interceptor) {
            okHttpClientBuilder.addNetworkInterceptor(interceptor);
            return this;
        }
    
    
        public List handlers() {
            return handlers;
        }
    
        public HttpKit addHandler(ResponseHandler handler) {
            handlers.add(handler);
            return this;
        }
    
        public Handler getDelivery() {
            return mDelivery;
        }
    
        public void build() {
            okHttpClient = okHttpClientBuilder.build();
        }
    
        private Request buildRequest(Params params) {
            Request.Builder builder = new Request.Builder();
            builder.url(params.getUrl());
            // 
            if (!params.getHeaders().isEmpty()) {
                for (Map.Entry header : params.getHeaders().entrySet()) {
                    if (header.getKey() != null) {
                        builder.addHeader(header.getKey(), header.getValue());
                    }
                }
            }
            //      
            if (params.isMultipart()) {
                MultipartBody.Builder body = new MultipartBody.Builder();
                body.setType(MultipartBody.FORM);
                // url
                if (!params.getUrlParams().isEmpty()) {
                    for (Map.Entry param : params.getUrlParams().entrySet()) {
                        if (param.getKey() != null) {
                            body.addFormDataPart(param.getKey(), (String) param.getValue());
                        }
                    }
                }
                // file  
                for (Map.Entry param : params.getFileParams().entrySet()) {
                    File file = param.getValue();
                    if (file != null && file.exists()) {
                        RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
                        body.addFormDataPart(param.getKey(), file.getName(), fileBody);
                    }
                }
                builder.post(body.build());
                //    ,    Post    
            } else if (Params.METHOD_POST.equals(params.getMethod())) {
                FormBody.Builder body = new FormBody.Builder();
                body.add("i", CryptKit.encrypt(params.getUrlParams(), params.getUrl()));
                builder.post(body.build());
            }
            return builder.build();
        }
    
        //    
        public Response execute(Params params) throws IOException {
            Request request = buildRequest(params);
    
            Call call = okHttpClient.newCall(request);
            return call.execute();
        }
    
        /**
         * get    parseNetworkResponse  ,     
         *
         * @param params
         * @param callback
         */
        public void get(Params params, final HttpCallback callback) {
            Request request = buildRequest(params);
    
            if (callback != null) callback.onStarted(request);
            Call call = okHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    sendFail(new ApiException(e), callback);
                }
    
                @Override
                public void onResponse(Call call, Response response) {
                    try {
                        if (call.isCanceled()) {
                            sendFail(new ApiException("  ", -1), callback);
                            return;
                        }
    
                        Object o = callback.parseNetworkResponse(response);
                        sendSuccess(o, callback);
                    } catch (ApiException e) {
                        sendFail(e, callback);
                    } finally {
                        if (response.body() != null)
                            response.body().close();
                    }
                }
            });
        }
    
        public void post(final Params params, final HttpCallback callback) {
            if (params == null || callback == null) {
                Log4a.e("post params null");
                return;
            }
            Request request = buildRequest(params);
    
            if (callback != null) callback.onStarted(request);
            Call call = okHttpClient.newCall(request);
            Log4a.e("======>post "+params.getUrl());
            Log4a.e("======>   params:"+params.toString());
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    sendFail(new ApiException(e.getCause()), callback);
                }
    
                @Override
                public void onResponse(Call call, Response response) {
                    try {
                        if (call.isCanceled()) {
                            sendFail(new ApiException("  ", -1), callback);
                            return;
                        }
    
                        Object o = callback.parseNetworkResponse(response);
                        sendSuccess(o, callback);
                    } catch (ApiException e) {
                        sendFail(e, callback);
                    } finally {
                        if (response.body() != null)
                            response.body().close();
                    }
                }
            });
        }
    
        private void sendFail(final ApiException e, final HttpCallback callback) {
            if (callback == null) return;
    
            mDelivery.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (callback != null) {
                            callback.onError(e);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    
        private void sendSuccess(final Object object, final HttpCallback callback) {
            if (callback == null) return;
    
            mDelivery.post(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (callback != null && object != null) {
                            callback.onResponse(object);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
    

    4.サブクラスカスタムCallBackメソッド解析データなど、対応する操作を実行
    public abstract class JSONCallback extends TypeToken implements HttpKit.HttpCallback {
    
        private Type mClass;//    List   Student type
    
        public JSONCallback() {
            mClass = getType();
        }
    
        public void onStarted(Request request) {
        }
    
        public void onProgressChanged(float progress, long total) {
    
        }
    
        /**
         * response    
         *
         * @param response
         * @return
         */
        @Deprecated
        public boolean validateReponse(Response response) {
            return true;
        }
    
        public T parseNetworkResponse(Response response) throws ApiException {
            String resp = "";
            String data = "";
            int status;
            String message;
    
            try {
                resp = response.body().string();
                Log4a.e("======>> response:"+response.request().url().url());
                Log4a.json(resp);
            } catch (IOException e) {
                throw new ApiException(e);
            }
    
            try {
                JSONObject jsonObject = new JSONObject(resp);
                status = jsonObject.getInt("code");
                message = jsonObject.getString("message");
                if (status == 1000 && jsonObject.has("data")) {
                    data = jsonObject.getString("data");
                }
            } catch (JSONException e) {
                throw new ApiException(e);
            }
    
            List handlers = HttpKit.me().handlers();
            if (handlers != null && handlers.size() > 0) {
                for (ResponseHandler handler : handlers)
                    handler.onHandler(status, message, response.request().url().url().getPath());
            }
    
            if (status != 1000) {
                throw new ApiException(message, status);
            }
    
            try {
                if (GsonKit.isSubObjectOf(mClass, List.class)) {
                    if ("".equals(data) || data == null||"{}".equals(data)) {
                        data = "[]";
                    }
                } else {
                    if ("".equals(data) || data == null||"[]".equals(data)) {
                        data = "{}";
                    }
                }
                return GsonKit.fromJson(data, mClass);
            } catch (Exception e) {
                throw new ApiException(message, status, e);
            }
        }
    
        public void onError(ApiException e) {
            if (e.getStatus() == 0)
                ViewKit.shortToast("    ,     ");
            else if (e.getStatus() == -1) {// TODO: 2016/11/26
    
            } else if (!StringKit.isEmpty(e.getMessage()))
                ViewKit.shortToast(e.getMessage());
        }
    
        public abstract void onResponse(T response);
    }
    

    5.Cookieのいくつかの設定
    //     cookie   ,  
        public static HttpKit init(Context context) {
            me().setContext(context);
            return me();
        }
    
        private void setContext(Context context) {
            this.mContext = context;
            cookieStore = new PersistentCookieStore(mContext);//     cookie
            CookieJarImpl cookieJar = new CookieJarImpl(cookieStore);
            okHttpClientBuilder.cookieJar(cookieJar);
        }
        //  cookie
        public void setCookie(Uri uri, Cookie cookie) {
            HttpUrl httpUrl = new HttpUrl.Builder().scheme(uri.getScheme()).host(uri.getHost()).build();
            cookieStore.add(httpUrl, cookie);
        }
    
        public void removeAllCookie() {
            cookieStore.removeAll();
        }
    

    CookieJarImplの実現、PersistentCookieStoreの永久化コード、ネット上にあります、直接探します
    public class CookieJarImpl implements CookieJar {
        private CookieStore cookieStore;
    
        public CookieJarImpl(CookieStore cookieStore) {
            if (cookieStore == null)
                throw new IllegalArgumentException(String.format("cookieStore can not be null."));
            this.cookieStore = cookieStore;
        }
    
        @Override
        public synchronized void saveFromResponse(HttpUrl url, List cookies) {
            cookieStore.add(url, cookies);
        }
    
        @Override
        public synchronized List loadForRequest(HttpUrl url) {
            return cookieStore.get(url);
        }
    
        public CookieStore getCookieStore() {
            return cookieStore;
        }
    }