欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用Android的OkHttp包實現基于HTTP協(xié)議的文件上傳下載

 更新時間:2016年07月13日 14:51:03   作者:總李寫代碼  
OkHttp(GitHub主頁https://github.com/square/okhttp)是近來人氣攀升的一款安卓第三方HTTP包,這里我們來講解一下如何使用Android的OkHttp包實現基于HTTP協(xié)議的文件上傳下載:

OkHttp的HTTP連接基礎
雖然在使用 OkHttp 發(fā)送 HTTP 請求時只需要提供 URL 即可,OkHttp 在實現中需要綜合考慮 3 種不同的要素來確定與 HTTP 服務器之間實際建立的 HTTP 連接。這樣做的目的是為了達到最佳的性能。
首先第一個考慮的要素是 URL 本身。URL 給出了要訪問的資源的路徑。比如 URL http://www.baidu.com 所對應的是百度首頁的 HTTP 文檔。在 URL 中比較重要的部分是訪問時使用的模式,即 HTTP 還是 HTTPS。這會確定 OkHttp 所建立的是明文的 HTTP 連接,還是加密的 HTTPS 連接。
第二個要素是 HTTP 服務器的地址,如 baidu.com。每個地址都有對應的配置,包括端口號,HTTPS 連接設置和網絡傳輸協(xié)議。同一個地址上的 URL 可以共享同一個底層 TCP 套接字連接。通過共享連接可以有顯著的性能提升。OkHttp 提供了一個連接池來復用連接。
第三個要素是連接 HTTP 服務器時使用的路由。路由包括具體連接的 IP 地址(通過 DNS 查詢來發(fā)現)和所使用的代理服務器。對于 HTTPS 連接還包括通訊協(xié)商時使用的 TLS 版本。對于同一個地址,可能有多個不同的路由。OkHttp 在遇到訪問錯誤時會自動嘗試備選路由。
當通過 OkHttp 來請求某個 URL 時,OkHttp 首先從 URL 中得到地址信息,再從連接池中根據地址來獲取連接。如果在連接池中沒有找到連接,則選擇一個路由來嘗試連接。嘗試連接需要通過 DNS 查詢來得到服務器的 IP 地址,也會用到代理服務器和 TLS 版本等信息。當實際的連接建立之后,OkHttp 發(fā)送 HTTP 請求并獲取響應。當連接出現問題時,OkHttp 會自動選擇另外的路由進行嘗試。這使得 OkHttp 可以自動處理可能出現的網絡問題。當成功獲取到 HTTP 請求的響應之后,當前的連接會被放回到連接池中,提供給后續(xù)的請求來復用。連接池會定期把閑置的連接關閉以釋放資源。

文件上傳和下載實例:
1.不帶參數上傳文件

  /**
   * 上傳文件
   * @param actionUrl 接口地址
   * @param filePath 本地文件地址
   */
  public <T> void upLoadFile(String actionUrl, String filePath, final ReqCallBack<T> callBack) {
    //補全請求地址
    String requestUrl = String.format("%s/%s", BASE_URL, actionUrl);
    //創(chuàng)建File
    File file = new File(filePath);
    //創(chuàng)建RequestBody
    RequestBody body = RequestBody.create(MEDIA_OBJECT_STREAM, file);
    //創(chuàng)建Request
    final Request request = new Request.Builder().url(requestUrl).post(body).build();
    final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
    call.enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        Log.e(TAG, e.toString());
        failedCallBack("上傳失敗", callBack);
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
          String string = response.body().string();
          Log.e(TAG, "response ----->" + string);
          successCallBack((T) string, callBack);
        } else {
          failedCallBack("上傳失敗", callBack);
        }
      }
    });
  }

2.帶參數上傳文件

/**
   *上傳文件
   * @param actionUrl 接口地址
   * @param paramsMap 參數
   * @param callBack 回調
   * @param <T>
   */
  public <T>void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, final ReqCallBack<T> callBack) {
    try {
      //補全請求地址
      String requestUrl = String.format("%s/%s", upload_head, actionUrl);
      MultipartBody.Builder builder = new MultipartBody.Builder();
      //設置類型
      builder.setType(MultipartBody.FORM);
      //追加參數
      for (String key : paramsMap.keySet()) {
        Object object = paramsMap.get(key);
        if (!(object instanceof File)) {
          builder.addFormDataPart(key, object.toString());
        } else {
          File file = (File) object;
          builder.addFormDataPart(key, file.getName(), RequestBody.create(null, file));
        }
      }
      //創(chuàng)建RequestBody
      RequestBody body = builder.build();
      //創(chuàng)建Request
      final Request request = new Request.Builder().url(requestUrl).post(body).build();
      //單獨設置參數 比如讀取超時時間
      final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
      call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
          Log.e(TAG, e.toString());
          failedCallBack("上傳失敗", callBack);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
          if (response.isSuccessful()) {
            String string = response.body().string();
            Log.e(TAG, "response ----->" + string);
            successCallBack((T) string, callBack);
          } else {
            failedCallBack("上傳失敗", callBack);
          }
        }
      });
    } catch (Exception e) {
      Log.e(TAG, e.toString());
    }
  }

3.帶參數帶進度上傳文件

 /**
   *上傳文件
   * @param actionUrl 接口地址
   * @param paramsMap 參數
   * @param callBack 回調
   * @param <T>
   */
  public <T> void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, final ReqProgressCallBack<T> callBack) {
    try {
      //補全請求地址
      String requestUrl = String.format("%s/%s", upload_head, actionUrl);
      MultipartBody.Builder builder = new MultipartBody.Builder();
      //設置類型
      builder.setType(MultipartBody.FORM);
      //追加參數
      for (String key : paramsMap.keySet()) {
        Object object = paramsMap.get(key);
        if (!(object instanceof File)) {
          builder.addFormDataPart(key, object.toString());
        } else {
          File file = (File) object;
          builder.addFormDataPart(key, file.getName(), createProgressRequestBody(MEDIA_OBJECT_STREAM, file, callBack));
        }
      }
      //創(chuàng)建RequestBody
      RequestBody body = builder.build();
      //創(chuàng)建Request
      final Request request = new Request.Builder().url(requestUrl).post(body).build();
      final Call call = mOkHttpClient.newBuilder().writeTimeout(50, TimeUnit.SECONDS).build().newCall(request);
      call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
          Log.e(TAG, e.toString());
          failedCallBack("上傳失敗", callBack);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
          if (response.isSuccessful()) {
            String string = response.body().string();
            Log.e(TAG, "response ----->" + string);
            successCallBack((T) string, callBack);
          } else {
            failedCallBack("上傳失敗", callBack);
          }
        }
      });
    } catch (Exception e) {
      Log.e(TAG, e.toString());
    }
  }

4.創(chuàng)建帶進度RequestBody

 /**
   * 創(chuàng)建帶進度的RequestBody
   * @param contentType MediaType
   * @param file 準備上傳的文件
   * @param callBack 回調
   * @param <T>
   * @return
   */
  public <T> RequestBody createProgressRequestBody(final MediaType contentType, final File file, final ReqProgressCallBack<T> callBack) {
    return new RequestBody() {
      @Override
      public MediaType contentType() {
        return contentType;
      }

      @Override
      public long contentLength() {
        return file.length();
      }

      @Override
      public void writeTo(BufferedSink sink) throws IOException {
        Source source;
        try {
          source = Okio.source(file);
          Buffer buf = new Buffer();
          long remaining = contentLength();
          long current = 0;
          for (long readCount; (readCount = source.read(buf, 2048)) != -1; ) {
            sink.write(buf, readCount);
            current += readCount;
            Log.e(TAG, "current------>" + current);
            progressCallBack(remaining, current, callBack);
          }
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    };
  }

5.不帶進度文件下載  

 /**
   * 下載文件
   * @param fileUrl 文件url
   * @param destFileDir 存儲目標目錄
   */
  public <T> void downLoadFile(String fileUrl, final String destFileDir, final ReqCallBack<T> callBack) {
    final String fileName = MD5.encode(fileUrl);
    final File file = new File(destFileDir, fileName);
    if (file.exists()) {
      successCallBack((T) file, callBack);
      return;
    }
    final Request request = new Request.Builder().url(fileUrl).build();
    final Call call = mOkHttpClient.newCall(request);
    call.enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        Log.e(TAG, e.toString());
        failedCallBack("下載失敗", callBack);
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        InputStream is = null;
        byte[] buf = new byte[2048];
        int len = 0;
        FileOutputStream fos = null;
        try {
          long total = response.body().contentLength();
          Log.e(TAG, "total------>" + total);
          long current = 0;
          is = response.body().byteStream();
          fos = new FileOutputStream(file);
          while ((len = is.read(buf)) != -1) {
            current += len;
            fos.write(buf, 0, len);
            Log.e(TAG, "current------>" + current);
          }
          fos.flush();
          successCallBack((T) file, callBack);
        } catch (IOException e) {
          Log.e(TAG, e.toString());
          failedCallBack("下載失敗", callBack);
        } finally {
          try {
            if (is != null) {
              is.close();
            }
            if (fos != null) {
              fos.close();
            }
          } catch (IOException e) {
            Log.e(TAG, e.toString());
          }
        }
      }
    });
  }

6.帶進度文件下載

 /**
   * 下載文件
   * @param fileUrl 文件url
   * @param destFileDir 存儲目標目錄
   */
  public <T> void downLoadFile(String fileUrl, final String destFileDir, final ReqProgressCallBack<T> callBack) {
    final String fileName = MD5.encode(fileUrl);
    final File file = new File(destFileDir, fileName);
    if (file.exists()) {
      successCallBack((T) file, callBack);
      return;
    }
    final Request request = new Request.Builder().url(fileUrl).build();
    final Call call = mOkHttpClient.newCall(request);
    call.enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        Log.e(TAG, e.toString());
        failedCallBack("下載失敗", callBack);
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        InputStream is = null;
        byte[] buf = new byte[2048];
        int len = 0;
        FileOutputStream fos = null;
        try {
          long total = response.body().contentLength();
          Log.e(TAG, "total------>" + total);
          long current = 0;
          is = response.body().byteStream();
          fos = new FileOutputStream(file);
          while ((len = is.read(buf)) != -1) {
            current += len;
            fos.write(buf, 0, len);
            Log.e(TAG, "current------>" + current);
            progressCallBack(total, current, callBack);
          }
          fos.flush();
          successCallBack((T) file, callBack);
        } catch (IOException e) {
          Log.e(TAG, e.toString());
          failedCallBack("下載失敗", callBack);
        } finally {
          try {
            if (is != null) {
              is.close();
            }
            if (fos != null) {
              fos.close();
            }
          } catch (IOException e) {
            Log.e(TAG, e.toString());
          }
        }
      }
    });
  }

7.接口ReqProgressCallBack.java實現
public interface ReqProgressCallBack<T> extends ReqCallBack<T>{
  /**
   * 響應進度更新
   */
  void onProgress(long total, long current);
}
8.進度回調實現
  /**
   * 統(tǒng)一處理進度信息
   * @param total  總計大小
   * @param current 當前進度
   * @param callBack
   * @param <T>
   */
  private <T> void progressCallBack(final long total, final long current, final ReqProgressCallBack<T> callBack) {
    okHttpHandler.post(new Runnable() {
      @Override
      public void run() {
        if (callBack != null) {
          callBack.onProgress(total, current);
        }
      }
    });
  }

相關文章

  • Android讀取手機通訊錄聯系人到自己項目

    Android讀取手機通訊錄聯系人到自己項目

    這篇文章主要為大家詳細介紹了Android讀取手機通訊錄聯系人到自己項目,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • Android實現加載時提示“正在加載,請稍后”的方法

    Android實現加載時提示“正在加載,請稍后”的方法

    在現在的很多應用中,當在加載的時候,如果頁面動態(tài)數據較多,會有很長一段時間的空白頁面,如果加上這個頁面正在加載的提示,使得應用更加人性化。這篇文章就給大家分享了在 Android實現加載時提示“正在加載,請稍后”的方法,有需要的朋友們可以參考借鑒。
    2016-10-10
  • android開發(fā)教程之startActivityForResult使用方法

    android開發(fā)教程之startActivityForResult使用方法

    這篇文章主要介紹了android開發(fā)教程之startActivityForResult使用方法,需要的朋友可以參考下
    2014-03-03
  • android輸入框內容改變的監(jiān)聽事件實例

    android輸入框內容改變的監(jiān)聽事件實例

    下面小編就為大家分享一篇android輸入框內容改變的監(jiān)聽事件實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-02-02
  • Android自定義ImageView實現點擊兩張圖片切換效果

    Android自定義ImageView實現點擊兩張圖片切換效果

    這篇文章主要為大家詳細介紹了Android自定義ImageView實現點擊兩張圖片切換效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Android BroadcastReceiver廣播注冊方式總結

    Android BroadcastReceiver廣播注冊方式總結

    這篇文章主要介紹了Android BroadcastReceiver廣播注冊方式總結的相關資料,需要的朋友可以參考下
    2017-01-01
  • 淺析Android中強大的Dialog

    淺析Android中強大的Dialog

    下面將通過一個小實例,來像大家展示Android功能強大的Dialog,代碼都寫了詳細的注釋,讀者不妨試著手動去敲
    2013-10-10
  • Android自定義實現淘寶下拉刷新效果

    Android自定義實現淘寶下拉刷新效果

    這篇文章主要為大家詳細介紹了Android自定義實現淘寶下拉刷新效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Flutter Dio二次封裝的實現

    Flutter Dio二次封裝的實現

    這篇文章主要介紹了Flutter Dio二次封裝的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Android自定義控件之仿優(yōu)酷菜單

    Android自定義控件之仿優(yōu)酷菜單

    這篇文章主要為大家詳細介紹了Android自定義控件之仿優(yōu)酷菜單的相關資料,感興趣的小伙伴們可以參考一下
    2016-06-06

最新評論