NoHttp1.1發佈,完美切入OKHttp、RxJava

NoHttp Logo

NoHttp1.1.0發佈,支持與RxJava完美結合、支持一句話切換底層OkHttpURLConnection,支持緩存數據到DB或者SD卡,支持Cookie的自動維護,完美支持Restful風格的接口,比Retrofit更簡單易用。 java

NoHttp 源碼地址:github.com/yanzhenjie/… android

NoHttp詳細使用文檔:doc.nohttp.netgit

歡迎加入QQ交流羣:547839514github


效果預覽

框架特性

比Retrofit使用更簡單、更易用。數據庫

  • 動態配置底層框架爲OkHttp、HttpURLConnection
  • RxJava完美結合,支持異步請求、支持同步請求
  • 多文件上傳,支持大文件上傳,表單提交數據
  • 文件下載、上傳下載、上傳和下載的進度回調、錯誤回調
  • 支持Json、xml、Map、List的提交
  • 完美的Http緩存模式,可指定緩存到數據庫、SD卡,緩存數據已安全加密
    • 在6.0以上手機緩存到SD卡時須要請求運行時權限:AndPermission
  • 自定義Request,直接請求JsonObject、JavaBean等
  • Cookie的自動維持,App重啓、關開機後還持續維持
  • http 301 302 303 304 307重定向,支持多層嵌套重定向
  • Https、自簽名網站Https的訪問、支持雙向驗證
  • 失敗重試機制,支持請求優先級
  • GET、POST、PUT、PATCH、HEAD、DELETE、OPTIONS、TRACE等請求協議
  • 用隊列保存請求,平均分配多線程的資源,支持多個請求併發
  • 支持取消某個請求、取消指定多個請求、取消全部請求

使用方法

AndroidStudio使用方式

  • 若是使用HttpURLConnection做爲網絡層:
    compile 'com.yolanda.nohttp:nohttp:1.1.0'複製代碼
  • 若是要使用OkHttp做爲網絡層,請再依賴:
    compile 'com.yanzhenjie.nohttp:okhttp:1.1.0'複製代碼

Eclipse使用方式

初始化

NoHttp初始化須要一個Context,最好在ApplicationonCreate()中初始化,記得在manifest.xml中註冊Applicationjson

通常狀況下只須要這樣初始化

直接初始化後,一切採用默認設置。api

NoHttp.initialize(this);複製代碼

若是須要自定義配置更多信息

  • 超時配置,默認10s緩存

    NoHttp.initialize(this, new NoHttp.Config()
      // 設置全局鏈接超時時間,單位毫秒
      .setConnectTimeout(30 * 1000)
      // 設置全局服務器響應超時時間,單位毫秒
      .setReadTimeout(30 * 1000)
    );複製代碼
  • 配置緩存,默認保存在數據庫

    NoHttp.initialize(this, new NoHttp.Config()
      ...
      // 保存到數據庫
      .setCacheStore(
          new DBCacheStore(this).setEnable(true) // 若是不使用緩存,設置false禁用。
      )
      // 或者保存到SD卡
      .setCacheStore(
          new DiskCacheStore(this)
      )
    );複製代碼
  • 配置Cookie保存的位置,默認保存在數據庫

    NoHttp.initialize(this, new NoHttp.Config()
      ...
      // 默認保存數據庫DBCookieStore,開發者能夠本身實現。
      .setCookieStore(
          new DBCookieStore(this).setEnable(false) // 若是不維護cookie,設置false禁用。
      )
    );複製代碼
  • 配置網絡層

    NoHttp.initialize(this, new NoHttp.Config()
      ...
      // 使用HttpURLConnection
      .setNetworkExecutor(new URLConnectionNetworkExecutor())
      // 使用OkHttp
      .setNetworkExecutor(new OkHttpNetworkExecutor())
    );複製代碼

權限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />複製代碼

友好的調試模式

Logger.setDebug(true);// 開啓NoHttp的調試模式, 配置後可看到請求過程、日誌和錯誤信息。
Logger.setTag("NoHttpSample");// 設置NoHttp打印Log的tag。複製代碼

開啓NoHttp的調試模式後可看到請求過程、日誌和錯誤信息,基本不用抓包。能夠看到請求頭、請求數據、響應頭、Cookie等,並且打印出的Log很是整齊。

因此說,若是你使用過程當中遇到什麼問題了,開啓調試模式,一切妖魔鬼怪都會現形的。

第三方異步框架

能夠與RxJava、RxAndroid、RxBus、EventBus等第三方異步任務框架完美結合使用,這裏在demo中給出了和RxJava一塊兒使用的代碼。

RxJava

NoHttp能夠和RxJava完美結合,這裏列出如何使用,具體的封裝請參考Demo的RxNoHttp。

Request<UserInfo> request = new JavaBeanRequest<>(url, UserInfo.class);
RxNoHttp.request(this, request, new SimpleSubscriber<Response<UserInfo>>() {
    @Override
    public void onNext(Response<YanZhenjie> entityResponse) {
        // 直接拿到實體對象
        UserInfo userInfo = entiryResponse.get();
    }
});複製代碼

請求隊列

RequestQueue requestQueue = NoHttp.newRequestQueue();
// 若是要指定併發值,傳入數字便可:NoHttp.newRequestQueue(3);

// 發起請求
requestQueue.add(what, request, responseListener);複製代碼
  • 添加請求到隊列時有一個what,這個what會在responseLisetener響應時回調給開發者,因此開發者能夠用一個responseLisetener接受多個請求的響應,用what來區分結果。而不用像有的框架同樣,每個請求都要new一個callback。
  • 強烈建議把生成隊列寫成懶漢單例模式,由於每新建隊列就會new出相應個數的線程來,同時只有線程數固定了,隊列的做用纔會發揮到最大。

幾種數據類型請求

String請求

Request<String> request = NoHttp.createStringRequest(url, RequestMethod.GET);
requestQueue.add(0, request, listener);複製代碼

Json請求

// JsonObject
Request<JSONObject> objRequest = NoHttp.createJsonObjectRequest(url, RequestMethod.POST);
requestQueue.add(0, objRequest, listener);

// JsonArray
Request<JSONArray> arrayRequest = NoHttp.createJsonArrayRequest(url, RequestMethod.PUT);
requestQueue.add(0, arrayRequest, listener);複製代碼

Bitmap請求

Request<Bitmap> request = NoHttp.createImageRequest(url, RequestMethod.DELETE);
requestQueue.add(0, request, listener);複製代碼

請求FastJson與Gson

// FastJson
Request<JSONObject> request = new FastJsonRequest(url, RequestMethod.POST);
requestQueue.add(0, request, listener);複製代碼

直接請求JavaBean

// 內部使用Gson、FastJson解析成JavaBean
Request<UserInfo> request = new JavaBeanRequest(url, RequestMethod.GET);
requestQueue.add(0, request, listener);複製代碼

添加參數

Request<JSONObject> request = new JavaBeanRequest(url, RequestMethod.POST);
   .add("name", "yoldada") // String類型
   .add("age", 18) // int類型
   .add("sex", '0') // char類型
   .add("time", 16346468473154) // long類型

   // 添加Bitmap
   .add("head", new BitmapBinary(bitmap))
   // 添加File
   .add("head", new FileBinary(file))
   // 添加ByteArray
   .add("head", new ByteArrayBinary(byte[]))
   // 添加InputStream
   .add("head", new InputStreamBinary(inputStream));複製代碼

文件上傳實現了http表單的標準協議,知足了廣大開發者的需求,有如下幾種形式:

  • 單個文件

    Request<String> request = ...
    request.add("file", new FileBinary(file));複製代碼
  • 上傳多個文件、多個Key多個文件形式
    這裏能夠添加各類形式的文件,File、Bitmap、InputStream、ByteArray。

    Request<String> request = ...
    request.add("file1", new FileBinary(File));
    request.add("file2", new FileBinary(File));
    request.add("file3", new InputStreamBinary(InputStream));
    request.add("file4", new ByteArrayBinary(byte[]));
    request.add("file5", new BitmapBinary(Bitmap));複製代碼
  • 上傳多個文件、一個Key多個文件形式

    Request<String> request = ...
    List<Binary> fileList = new ArrayList<>(4);
    fileList.add(new FileBinary(File));
    fileList.add(new InputStreamBinary(InputStream));
    fileList.add(new ByteArrayBinary(byte[]));
    fileList.add(new BitmapStreamBinary(Bitmap));
    request.add("file_list", fileList);複製代碼

提交請求包體

提交Body分爲提交Json、提交String、提交Xml、提交流等,具體用法以下:

// 提交普通String
request.setDefineRequestBody(String, ContentType);

// 提交json字符串
request.setDefineRequestBodyForJson(JsonString)

// 提交jsonObject對象,其實仍是json字符串
request.setDefineRequestBodyForJson(JSONObject)

// 提交xml字符串
request.setDefineRequestBodyForXML(XmlString)

// 提交字體Body,好比File(這跟表單上傳不同的),能夠轉爲InputStream來提交
request.setDefineRequestBody(InputStream, ContentType)複製代碼

同步請求

在當前線程發起請求,在線程這麼使用。

Request<String> request = NoHttp.createStringRequest(url, RequestMethod.DELETE);
Response<String> response = NoHttp.startRequestSync(request);
if (response.isSucceed()) {
    // 請求成功
} else {
    // 請求失敗
}複製代碼

五大緩存模式

NoHttp的緩存很是強大,支持緩存到數據庫、換到SD卡等,而且不論緩存在數據庫或者SD,NoHttp都把數據進行了加密,須要在初始化的時候配置緩存的位置。

須要注意的是,在6.0以上的手機中若是要緩存在SD卡,須要在請求以前,須要請求運行時權限,若是你不懂運行時權限,能夠看這個項目:AndPermission

NoHttp.initialize(this, new NoHttp.Config()
    ...
    // 保存到數據庫
    .setCacheStore(
        new DBCacheStore(this).setEnable(true) // 若是不使用緩存,設置false禁用。
    )
    // 或者保存到SD卡
    .setCacheStore(
        new DiskCacheStore(this)
    )
);複製代碼
  • 一、Default模式,實現http 304重定向緩存
    NoHttp自己是實現了RFC2616,因此這裏不用設置或者設置爲DEFAULT。

    Request<JSONObject> request = NoHttp.createJsonObjectRequest(url);
    request.setCacheMode(CacheMode.DEFAULT);複製代碼
  • 二、 當請求服務器失敗的時候,讀取緩存
    請求服務器成功則返回服務器數據,若是請求服務器失敗,讀取緩存數據返回。

    Request<JSONObject> request = NoHttp.createJsonObjectRequest(url);
    request.setCacheMode(CacheMode.REQUEST_NETWORK_FAILED_READ_CACHE);複製代碼
  • 三、若是發現有緩存直接成功,沒有緩存才請求服務器
    咱們知道ImageLoader的核心除了內存優化外,剩下一個就是發現把內地有圖片則直接使用,沒有則請求服務器,因此NoHttp這一點很是使用作一個ImageLoader。

    Request<Bitmap> request = NoHttp.createImageRequest(imageUrl);
    request.setCacheMode(CacheMode.IF_NONE_CACHE_REQUEST_NETWORK);複製代碼
  • 四、僅僅請求網絡
    這裏不會讀取緩存,也不支持Http304。

    Request<Bitmap> request = NoHttp.createImageRequest(imageUrl);
    request.setCacheMode(CacheMode.ONLY_REQUEST_NETWORK);
    ...複製代碼
  • 五、僅僅讀取緩存
    僅僅讀取緩存,不會請求網絡和其它操做。

    Request<Bitmap> request = NoHttp.createImageRequest(imageUrl);
    request.setCacheMode(CacheMode.ONLY_READ_CACHE);複製代碼

文件下載

由於下載文件代碼比較多,這裏貼關鍵部分,具體的請參考demo。

文件下載也是隊列,隊列和開頭所說的請求的隊列是同樣的。

  • 發起下載請求

    //下載文件
    downloadRequest = NoHttp.createDownloadRequest...
    // what 區分下載
    // downloadRequest 下載請求對象
    // downloadListener 下載監聽
    downloadQueue.add(0, downloadRequest, downloadListener);複製代碼
  • 暫停或者中止下載

    downloadRequest.cancel();複製代碼
  • 監聽下載過程

    private DownloadListener downloadListener = new DownloadListener() {
      @Override
      public void onStart(int what, boolean resume, long preLenght, Headers header, long count) {
          // 下載開始
      }
    
      @Override
      public void onProgress(int what, int progress, long downCount) {
          // 更新下載進度
      }
    
       @Override
      public void onFinish(int what, String filePath) {
          // 下載完成
       }
    
      @Override
      public void onDownloadError(int what, StatusCode code, CharSequence message) {
          // 下載發生錯誤
      }
    
      @Override
      public void onCancel(int what) {
          // 下載被取消或者暫停
      }
    };複製代碼

取消請求

NoHttp支持取消某個請求、取消指定多個請求、取消全部請求。

  • 取消單個請求
    直接調用請求對象的cancel方法。

    request.cancel();複製代碼
  • 從隊列中取消指定的請求
    在請求以前給請求set一個sign,取消的時候調用隊列的cancelBySign就能夠取消掉全部指定這個sign的請求。

    request1.setCancelSign(sign);
    request2.setCancelSign(sign);
    // 取消隊列中多個用sign標誌的請求
    queue.cancelBySign(sign);複製代碼
  • 取消隊列中全部請求

    queue.cancelAll();複製代碼

中止隊列

隊列中止後再添加請求到隊列後,請求不會被執行。

RequestQueue queue = NoHttp.newRequestQueue();
...

queue.stop();複製代碼

自定義請求

  • FastJsonRequest

    public class FastJsonRequest extends RestRequestor<JSONObject> {
    
      public FastJsonRequest(String url) {
          this(url, RequestMethod.GET);
      }
    
      public FastJsonRequest(String url, RequestMethod requestMethod) {
          super(url, requestMethod);
      }
    
      @Override
      public JSONObject parseResponse(Headers header, byte[] body) throws Throwable {
          String result = StringRequest.parseResponseString(headers, body);
          return JSON.parseObject(result);
      }
    }複製代碼
  • JavaBeanRequest,利用FastJson、Gson等把數據直接轉爲JavaBean

    public class JavaBeanRequest<T> extends RestRequest<T> {
      private Class<T> clazz;
    
      public JavaBeanRequest(String url, Class<T> clazz) {
          this(url, RequestMethod.GET, clazz);
      }
    
      public JavaBeanRequest(String url, RequestMethod requestMethod, Class<T> clazz) {
          super(url, requestMethod);
          this.clazz = clazz;
      }
    
      @Override
      public T parseResponse(Headers header, byte[] body) throws Throwable {
          String response = StringRequest.parseResponseString(header, body);
    
          // 這裏若是數據格式錯誤,或者解析失敗,會在失敗的回調方法中返回 ParseError 異常。
          return JSON.parseObject(response, clazz);
      }
    }複製代碼
  • 使用自定義請求

// 使用FastJson自定義請求
Request<JSONObject> request = new FastJsonRequest(url, requestMethod);
queue.add(what, mRequest, listener);
// 直擊請求JavaBean
Request<UserInfo> request = new JavaBeanRequest(url, UserInfo.class);
queue.add(what, request, listener);複製代碼

代碼混淆

  1. NoHttp所有的類均可以混淆。
  2. NoHttp設計到兼容高版本系統的api採用反射調用,因此全部類均可以被混淆

  3. 若是你非要keep的話,以下配置便可

    -dontwarn com.yolanda.nohttp.**
    -keep class com.yolanda.nohttp.**{*;}複製代碼

NoHttp 源碼地址:github.com/yanzhenjie/…

License

Copyright 2016 Yan Zhenjie

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.複製代碼
相關文章
相關標籤/搜索