1. 程式人生 > >okhttp-OkGo(okhttp-util升級版)網路請求框架(一)

okhttp-OkGo(okhttp-util升級版)網路請求框架(一)

這裡寫圖片描述

OkGo - OkHttpUtils-2.0.0 升級後改名 OkGo,全新完美支援RxJava

該庫是封裝了okhttp的標準RESTful風格的網路框架,可以與RxJava完美結合,比Retrofit更簡單易用。支援大檔案上傳下載,上傳進度回撥,下載進度回撥,表單上傳(多檔案和多引數一起上傳),鏈式呼叫,可以自定義返回物件,支援Https和自簽名證書,支援超時自動重連,支援cookie與session的自動管理,支援四種快取模式快取網路資料,支援301、302重定向,擴充套件了統一的上傳管理和下載管理功能。

介紹

1.新增依賴

Android studio

compile 'com.lzy.net:okgo:2.1.4'
//可以單獨使用,不需要依賴下方的擴充套件包 compile 'com.lzy.net:okrx:0.1.2'//RxJava擴充套件支援,根據需要新增 compile 'com.lzy.net:okserver:1.1.3'//下載管理和上傳管理擴充套件,根據需要新增 或者 compile 'com.lzy.net:okgo:+' //版本號使用 + 可以自動引用最新版 compile 'com.lzy.net:okrx:+' //版本號使用 + 可以自動引用最新版 compile 'com.lzy.net:okserver:+' //版本號使用 + 可以自動引用最新版

2.注意事項

  • okgo使用的okhttp的版本是最新的 3.4.1 版本,和以前的 2.x 的版本可能會存在衝突。
  • okrx是基於RxJava和RxAndroid的擴充套件,如果不需要可以不必引入
  • okserver是對okgo的擴充套件,統一了下載管理和上傳管理,對專案有需要做統一下載的可以考慮使用該擴充套件,不需要的可以直接使用okgo即可。
  • 對於快取模式使用,需要與返回物件相關的所有javaBean必須實現Serializable介面,否者會報NotSerializableException。
  • 使用快取時,如果不指定cacheKey,預設是用url帶引數的全路徑名為cacheKey。
  • 使用該網路框架時,必須要在 Application 中做初始OkGo.init(this);。

3.OkGo目前支援

  • 一般的 get,post,put,delete,head,options請求
  • 基於Post的大文字資料上傳
  • 多檔案和多引數統一的表單上傳
  • 支援一個key上傳一個檔案,也可以一個Key上傳多個檔案
  • 大檔案下載和下載進度回撥
  • 大檔案上傳和上傳進度回撥
  • 支援cookie的記憶體儲存和持久化儲存,支援傳遞自定義cookie
  • 支援304快取協議,擴充套件四種本地快取模式,並且支援快取時間控制
  • 支援301、302重定向
  • 支援自定義超時自動重連次數
  • 支援鏈式呼叫
  • 支援可信證書和自簽名證書的https的訪問,支援雙向認證
  • 支援根據Tag取消請求
  • 支援自定義泛型Callback,自動根據泛型返回物件

4.OkRx擴充套件功能

OkRx使用文件

  • 完美結合RxJava
  • 比Retrofit更簡單方便
  • 網路請求和RxJava呼叫,一條鏈點到底
  • 支援Json資料的自動解析轉換
  • OkGo包含的所有請求功能,OkRx全部支援

5.OkServer擴充套件功能

5.1 統一的檔案下載管理(DownloadManager):

  • 結合OkGo的request進行網路請求,支援與OkGo保持相同的全域性公共引數,同時支援請求傳遞引數
  • 支援斷點下載,支援突然斷網,強殺程序後,斷點依然有效
  • 支援 下載 暫停 等待 停止 出錯 完成 六種下載狀態
  • 所有下載任務按照taskKey區分,切記不同的任務必須使用不一樣的key,否者斷點會發生覆蓋
  • 相同的下載url地址如果使用不一樣的taskKey,也會認為是兩個下載任務
  • 默認同時下載數量為3個,預設下載路徑/storage/emulated/0/download,下載路徑和下載數量都可以在程式碼中配置
  • 下載檔名可以自己定義,也可以不傳,框架自動解析響應頭或者url地址獲得檔名,如果都沒獲取到,使用default作為檔名

5.2 統一的檔案上傳管理(UploadManager)

  • 結合OkGo的request進行網路請求,支援與OkGo保持相同的全域性公共引數,同時支援請求傳遞引數
  • 上傳只能使用Post, Put, Delete, Options 這四種請求,不支援Get, Head
  • 該上傳管理為簡單管理,不支援斷點續傳或分片上傳,只是簡單的將所有上傳任務使用執行緒池進行了統一管理
  • 默認同時上傳數量為1個,該數列可以在程式碼中配置修改

使用

1.全域性配置

一般在 Aplication,或者基類中,只需要呼叫一次即可,可以配置除錯開關,全域性的超時時間,公共的請求頭和請求引數等資訊

public class MyApp extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        HttpHeaders headers = new HttpHeaders();
        HttpParams params = new HttpParams();
        //header不支援中文,不允許有特殊字元
        headers.put("commonHeaderKey1", "commonHeaderValue1");
        headers.put("commonHeaderKey2", "commonHeaderValue2");
        //param支援中文,直接傳,不要自己編碼
        params.put("commonParamsKey1", "commonParamsValue1");
        params.put("commonParamsKey2", "這裡支援中文引數");
        //OkGo初始化
        OkGo.init(this);
        //以下設定的所有引數是全域性引數,同樣的引數可以在請求的時候再設定一遍,那麼對於該請求來講,請求中的引數會覆蓋全域性引數
        //好處是全域性引數統一,特定請求可以特別定製引數
        try {
            OkGo.getInstance()
                    .debug("OkGo", Level.INFO,true)//開啟該除錯開關,列印級別INFO,最後的true表示是否列印okgo的內部異常,一般開啟方便除錯錯誤
                    .setConnectTimeout(OkGo.DEFAULT_MILLISECONDS)//全域性的連線超時時間 預設60秒
                    .setWriteTimeOut(OkGo.DEFAULT_MILLISECONDS)//全域性的讀取超時時間
                    .setReadTimeOut(OkGo.DEFAULT_MILLISECONDS)//全域性的寫入超時時間
                    .setCacheMode(CacheMode.NO_CACHE)//全域性統一設定快取模式,預設是不使用快取
                    .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)//全域性統一設定快取時間,預設永不過期
                    .setRetryCount(3)//全域性統一設定超時重連次數,預設為三次,最差的情況會請求4次(一次原始請求,三次重連請求),不需要可以設定為0
                    .setCookieStore(new PersistentCookieStore())//cookie持久化儲存,如果cookie不過期,則一直有效
                    .setCertificates()//方法一:信任所有證書,不安全有風險
                    .addCommonHeaders(Config.getHeaders())//設定全域性公共頭
                    .addCommonParams(Config.getParams());//設定全域性公共引數
            //.setCookieStore(new MemoryCookieStore()) //cookie使用記憶體快取(app退出後,cookie消失)
            //.setCertificates(new SafeTrustManager()) //方法二:自定義信任規則,校驗服務端證書
            //.setCertificates(getAssets().open("srca.cer"))//方法三:使用預埋證書,校驗服務端證書(自簽名證書)
            //.setCertificates(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"))
            //方法四:使用bks證書和密碼管理客戶端證書(雙向認證),使用預埋證書,校驗服務端證書(自簽名證書)
            //.setHostnameVerifier(new SafeHostnameVerifier())
            //配置https的域名匹配規則,詳細看demo的初始化介紹,不需要就不要加入,使用不當會導致https握手失敗,自定義
            //可以新增全域性攔截器,不需要就不要加入,錯誤寫法直接導致任何回撥不執行
//          .addInterceptor(new Interceptor() {
//                    @Override
//                    public Response intercept(Chain chain) throws IOException {
//                        return chain.proceed(chain.request());
//                    }
//                })
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

2.OkRx使用例項

1.基本請求(post)

//獲取string
 Subscription subscription = OkGo.post(Urls.URL_METHOD)
                    .headers("aaa", "111")
                    .params("bbb", "222")
                    .getCall(StringConvert.create(), RxAdapter.<String>create())//以上為產生請求事件,請求預設發生在IO執行緒
                    .doOnSubscribe(new Action0() {
                        @Override
                        public void call() {
                              //開始請求前顯示對話方塊
                        }
                    }).observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Action1<String>() {
                        @Override
                        public void call(String s) {
                            //請求成功
                        }
                    }, new Action1<Throwable>() {
                        @Override
                        public void call(Throwable throwable) {
                            //請求失敗
                        }
                    });
//使用JsonCallback解析JavaBean
 Subscription subscription = OkGo.post(Urls.URL_JSONOBJECT)
                        .headers("aaa", "111")//
                        .params("bbb", "222")//一定要注意這裡的寫法,JsonConvert最後的大括號千萬不能忘記
                        .getCall(new JsonConvert<LzyResponse<ServerModel>>() {}, RxAdapter.<LzyResponse<ServerModel>>create())//
                        .doOnSubscribe(new Action0() {
                            @Override
                            public void call() {
                                //開始請求前顯示對話方塊
                            }
                        })
                        .map(new Func1<LzyResponse<ServerModel>, ServerModel>() {
                            @Override
                            public ServerModel call(LzyResponse<ServerModel> response) {
                                return response.data;
                            }
                        })//
                        .observeOn(AndroidSchedulers.mainThread())//
                        .subscribe(new Action1<ServerModel>() {
                            @Override
                            public void call(ServerModel serverModel) {
                               //請求成功
                            }
                        }, new Action1<Throwable>() {
                            @Override
                            public void call(Throwable throwable) {
                                //請求失敗
                            }
                        });
//使用JsonCallback解析List&lt<JavaBean>;
Subscription subscription = ServerApi.getServerListModel("aaa", "bbb")//
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        showLoading();
                    }
                })
                .map(new Func1<LzyResponse<List<ServerModel>>, List<ServerModel>>() {
                    @Override
                    public List<ServerModel> call(LzyResponse<List<ServerModel>> response) {
                        return response.data;
                    }
                })
               .observeOn(AndroidSchedulers.mainThread())//
                .subscribe(new Action1<List<ServerModel>>() {
                    @Override
                    public void call(List<ServerModel> serverModels) {
                      //請求成功

                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                                 //請求失敗
                    }
                });
//post上傳string文字


Subscription subscription = OkGo.post(Urls.URL_TEXT_UPLOAD)
                .headers("bbb", "222")
                .upString("上傳的文字。。。")//上傳文字
                .getCall(StringConvert.create(), RxAdapter.<String>create())//以上為產生請求事件,請求預設發生在IO執行緒
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        //開始請求前顯示對話方塊
                    }
                }).observeOn(AndroidSchedulers.mainThread())//切換到主執行緒
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        //請求成功,關閉對話方塊
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        //請求失敗
                    }
                });
//post上傳json


Subscription subscription = OkGo.post(Urls.URL_TEXT_UPLOAD)//
                .headers("bbb", "222")//
                .upJson(jsonObject.toString())//post上傳json
                .getCall(StringConvert.create(), RxAdapter.<String>create())//以上為產生請求事件,請求預設發生在IO執行緒
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                      //開始請求前顯示對話方塊
                      }  }).observeOn(AndroidSchedulers.mainThread())//切換到主執行緒
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                       //請求成功,關閉對話方塊
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                       //請求失敗
                    }
                });

2.請求圖片


 Subscription subscription = OkGo.post(Urls.URL_IMAGE)
                .headers("aaa", "aaa")
                .params("bbb",  "bbb")
                .getCall(BitmapConvert.create(), RxAdapter.<Bitmap>create())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                       //
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//
                .subscribe(new Action1<Bitmap>() {
                    @Override
                    public void call(Bitmap bitmap) {
                        //請求成功
                        imageView.setImageBitmap(bitmap);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                           //請求失敗
                    }
                });
        addSubscribe(subscription);

3.檔案上傳

  ArrayList<File> files = new ArrayList<>();
        if (imageItems != null && imageItems.size() > 0) {
            for (int i = 0; i < imageItems.size(); i++) {
                files.add(new File(imageItems.get(i).path));
            }
        }

        //拼接引數
        OkGo.post(Urls.URL_FORM_UPLOAD)//
                .tag(this)//
                .headers("header1", "headerValue1")//
                .headers("header2", "headerValue2")//
                .params("param1", "paramValue1")//
                .params("param2", "paramValue2")//
//                .params("file1",new File("檔案路徑"))   //這種方式為一個key,對應一個檔案
//                .params("file2",new File("檔案路徑"))
//                .params("file3",new File("檔案路徑"))
                .addFileParams("file", files)           // 這種方式為同一個key,上傳多個檔案
                .getCall(StringConvert.create(), RxAdapter.<String>create())//
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        btnFormUpload.setText("正在上傳中...\n使用Rx方式做進度監聽稍顯麻煩,推薦使用回撥方式");
                    }
                })
                .observeOn(AndroidSchedulers.mainThread())//切換到主執行緒
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        btnFormUpload.setText("上傳完成");
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        showToast("請求失敗");
                    }
                });

4.下載檔案

OkGo.post(Urls.URL_DOWNLOAD)//
                .headers("aaa", "aaa")//
                .params("bbb", "bbb")//
                .getCall(new FileConvert(), RxAdapter.<File>create())
                .doOnSubscribe(new Action0() {
                    @Override
                    public void call() {
                        btnFileDownload.setText("正在下載中...\n使用Rx方式做進度監聽稍顯麻煩,推薦使用回撥方式");
                    }
                })//
                .observeOn(AndroidSchedulers.mainThread())//
                .subscribe(new Action1<File>() {
                    @Override
                    public void call(File file) {
                        btnFileDownload.setText("下載完成");
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        throwable.printStackTrace();

                        showToast("請求失敗");
                    }
                });