最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

  /**
   * 上傳文件
   * @param actionUrl 接口地址
   * @param filePath 本地文件地址
   */
  public <T> void upLoadFile(String actionUrl, String filePath, final ReqCallBack<T> callBack) {
    //補(bǔ)全請求地址
    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ǔ)全請求地址
      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();
      //單獨設(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ǔ)全請求地址
      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 存儲目標(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 存儲目標(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實現(xiàn)
public interface ReqProgressCallBack<T> extends ReqCallBack<T>{
  /**
   * 響應(yīng)進(jìn)度更新
   */
  void onProgress(long total, long current);
}
8.進(jìn)度回調(diào)實現(xiàn)
  /**
   * 統(tǒng)一處理進(jìn)度信息
   * @param total  總計大小
   * @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)文章

  • 詳解Flutter中key的正確使用方式

    詳解Flutter中key的正確使用方式

    這篇文章主要為大家介紹了詳解Flutter中key的正確使用方式,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • Android利用GridView實現(xiàn)單選效果

    Android利用GridView實現(xiàn)單選效果

    本篇文章主要介紹了Android利用GridView實現(xiàn)單選效果的相關(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-05-05
  • android viewpaper實例探討

    android viewpaper實例探討

    本文將提供一個android viewpaper實例實現(xiàn)過程,需要了解更多的朋友可以參考下
    2012-12-12
  • Android圖片三級緩存開發(fā)

    Android圖片三級緩存開發(fā)

    這篇文章主要為大家詳細(xì)介紹了Android圖片三級緩存開發(fā)的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • android獲取當(dāng)前手機(jī)號示例程序

    android獲取當(dāng)前手機(jī)號示例程序

    這篇文章主要介紹了android如何獲取當(dāng)前手機(jī)號的方法,大家參考使用吧
    2013-11-11
  • Android編程Widget創(chuàng)建與使用方法簡明教程

    Android編程Widget創(chuàng)建與使用方法簡明教程

    這篇文章主要介紹了Android編程Widget創(chuàng)建與使用方法,結(jié)合實例形式分析了Widget的功能、使用方法與相關(guān)注意事項,需要的朋友可以參考下
    2016-10-10
  • Android?完整購物商城界面的實現(xiàn)案例

    Android?完整購物商城界面的實現(xiàn)案例

    這篇文章為大家?guī)硪粋€Android?完整購物商城的界面具體的實現(xiàn),案例中含有商品列表的顯示,為商城最重要的功能之一,感興趣的朋友來看看吧
    2022-03-03
  • Android編程設(shè)計模式之策略模式詳解

    Android編程設(shè)計模式之策略模式詳解

    這篇文章主要介紹了Android編程設(shè)計模式之策略模式,結(jié)合實例形式詳細(xì)分析了Android策略模式的概念、原理、實現(xiàn)方法及相關(guān)注意事項,需要的朋友可以參考下
    2017-12-12
  • 在Android上實現(xiàn)HttpServer的示例代碼

    在Android上實現(xiàn)HttpServer的示例代碼

    本篇文章主要介紹了在Android上實現(xiàn)HttpServer的示例代碼,實現(xiàn)Android本地的微型服務(wù)器,具有一定的參考價值,有興趣的可以了解一下
    2017-08-08
  • android 獲取屏幕尺寸

    android 獲取屏幕尺寸

    這篇文章主要介紹了android 獲取屏幕尺寸的方法,需要的朋友可以參考下
    2015-03-03

最新評論

临沂市| 九江市| 云龙县| 兰考县| 酒泉市| 新巴尔虎左旗| 东至县| 中宁县| 电白县| 安西县| 镇雄县| 巩留县| 抚宁县| 宁安市| 绍兴县| 邳州市| 明光市| 景东| 黔西| 甘德县| 师宗县| 屯门区| 日土县| 合川市| 临高县| 蓬溪县| 洪江市| 南昌县| 佳木斯市| 山东省| 桦川县| 阿勒泰市| 永胜县| 天津市| 石嘴山市| 高安市| 辽源市| 高陵县| 新河县| 兴义市| 宣城市|