亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

文件上傳和下載實(shí)例:
1.不帶參數(shù)上傳文件

  /**
   * 上傳文件
   * @param actionUrl 接口地址
   * @param filePath 本地文件地址
   */
  public <T> void upLoadFile(String actionUrl, String filePath, final ReqCallBack<T> callBack) {
    //補(bǔ)全請(qǐng)求地址
    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.帶參數(shù)上傳文件

/**
   *上傳文件
   * @param actionUrl 接口地址
   * @param paramsMap 參數(shù)
   * @param callBack 回調(diào)
   * @param <T>
   */
  public <T>void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, final ReqCallBack<T> callBack) {
    try {
      //補(bǔ)全請(qǐng)求地址
      String requestUrl = String.format("%s/%s", upload_head, actionUrl);
      MultipartBody.Builder builder = new MultipartBody.Builder();
      //設(shè)置類型
      builder.setType(MultipartBody.FORM);
      //追加參數(shù)
      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();
      //單獨(dú)設(shè)置參數(shù) 比如讀取超時(shí)時(shí)間
      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.帶參數(shù)帶進(jìn)度上傳文件

 /**
   *上傳文件
   * @param actionUrl 接口地址
   * @param paramsMap 參數(shù)
   * @param callBack 回調(diào)
   * @param <T>
   */
  public <T> void upLoadFile(String actionUrl, HashMap<String, Object> paramsMap, final ReqProgressCallBack<T> callBack) {
    try {
      //補(bǔ)全請(qǐng)求地址
      String requestUrl = String.format("%s/%s", upload_head, actionUrl);
      MultipartBody.Builder builder = new MultipartBody.Builder();
      //設(shè)置類型
      builder.setType(MultipartBody.FORM);
      //追加參數(shù)
      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)建帶進(jìn)度RequestBody

 /**
   * 創(chuàng)建帶進(jìn)度的RequestBody
   * @param contentType MediaType
   * @param file 準(zhǔn)備上傳的文件
   * @param callBack 回調(diào)
   * @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.不帶進(jìn)度文件下載  

 /**
   * 下載文件
   * @param fileUrl 文件url
   * @param destFileDir 存儲(chǔ)目標(biāo)目錄
   */
  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.帶進(jìn)度文件下載

 /**
   * 下載文件
   * @param fileUrl 文件url
   * @param destFileDir 存儲(chǔ)目標(biāo)目錄
   */
  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實(shí)現(xiàn)
public interface ReqProgressCallBack<T> extends ReqCallBack<T>{
  /**
   * 響應(yīng)進(jìn)度更新
   */
  void onProgress(long total, long current);
}
8.進(jìn)度回調(diào)實(shí)現(xiàn)
  /**
   * 統(tǒng)一處理進(jìn)度信息
   * @param total  總計(jì)大小
   * @param current 當(dāng)前進(jìn)度
   * @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);
        }
      }
    });
  }

相關(guān)文章

最新評(píng)論