使用OkHttp下载文件时获取java.net.SocketTimeoutException

时间:2018-01-03 08:46:05

标签: android download okhttp

我正在使用OkHttp从服务器下载文件。 这是我的代码: 我为它设置了读写超时:

 public static final String API_BASE_URL = "http://XXXX:8080/tablet/";
    private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
      .connectTimeout(60,TimeUnit.SECONDS)
      .writeTimeout(60,TimeUnit.SECONDS);

这是我的createServiceFile

public static <S> S createServiceFile(Class<S> serviceClass, final String token) {
        if (token != null) {

            httpClient.addInterceptor(new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request original = chain.request();
                    Request.Builder requestBuilder = original.newBuilder()
                      .header("Authorization", token)
                      .header("Accept", "text/html,application/xhtml+xml,application/pdf,application/xml;q=0.9," +
                        "image/webp,audio/mpeg ,image/png,audio/mp4,image/jpeg,*/*;q=0.8")
                      .method(original.method(), original.body());
                    Request request = requestBuilder.build();
                    return chain.proceed(request);
                }
            });
        }
        OkHttpClient client = httpClient.build();
        Retrofit retrofit = builder.client(client).build();
        return retrofit.create(serviceClass);
    }

这是我编写SD卡响应的代码(响应contentLength为-1,因为服务器没有发送给我):

public DownloadRequest DownloadFile() {

    //Creating folder for Application in SD Card if it's not created yet in App Class!
    new java.io.File(G.DIR_APP).mkdirs();
    new java.io.File(G.DIR_MEDIA).mkdirs();

    APIService downloadService = ServiceGenerator.createServiceFile(APIService.class, G.TOKEN);
    downloadService.downloadFileWithDynamicUrlSync(url)//set URL of the  file
      .subscribeOn(Schedulers.newThread())
      .observeOn(Schedulers.io())
      .delay(30, TimeUnit.MILLISECONDS)
      .subscribe(new Observer<ResponseBody>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(ResponseBody responseBody) {

          Log.i(TAG, "On Next And Current App is: " + fileName);

          if (writeResponseBodyToDisk(responseBody)) {

            Log.i(TAG, fileName + "Downloaded successful");

            //This Download was successful Then try to set downloadResult true
            result = true;

          } else {
            result = false;
          }
        }

        @Override
        public void onError(Throwable e) {

          Log.i(TAG, "!!!!!!!!!!!!!!!!\n\nOn Error And Current App is: " +
            fileName + " And Error is" + e.toString() + "\n\n!!!!!!!!!!!!!!!!\n\n");

          //Set downloadResult false
          result = false;
          if (listener != null) {
            listener.onDownloadCompleteListener(false);
          }
        }

        @Override
        public void onComplete() {
          Log.i(TAG, "On Complete And Current App is: " + fileName);

          if (listener != null) {
            if (result) {
              listener.onDownloadCompleteListener(true);
            } else {
              listener.onDownloadCompleteListener(false);
            }
          }

        }
      });

    return this;
  }

此代码将写入对disck的响应:

  private boolean writeResponseBodyToDisk(ResponseBody body) {

    // Location to save downloaded file and filename
    java.io.File file = new java.io.File(destinationPath + fileName + "." + extension);

    try {

      InputStream inputStream = null;
      OutputStream outputStream = null;
      int bytesBuffered = 0;

      try {
        byte[] fileReader = new byte[bufferSize];

        downloadSize = 0;
        inputStream = body.byteStream();

        /*
         * If append requested we have to append new bytes to
         * Exists bytes on the storage
         */
        if (appendNeed) {
          outputStream = new FileOutputStream(file, true);
        } else {
          outputStream = new FileOutputStream(file);
        }

        while (true) {

          int read = inputStream.read(fileReader);
          if (read == -1) {
            break;
          }

          bytesBuffered += read;

          if (bytesBuffered > 1024 * 1024) {
            //  outputStream.write(fileReader, 0, read);
            outputStream.flush();
            bytesBuffered = 0;
          }
          outputStream.write(fileReader, 0, read);
          downloadSize += read;

          percent = (int) (100.0f * (float) downloadSize / totalSize);
          if (listener != null) {
            listener.onDownloadPercentListener(percent);
          }
        }
        outputStream.flush();
        inputStream.close();
        outputStream.close();


        return true;
      } catch (IOException e) {

        Log.i(TAG, "Error in download" + e.toString());
        return false;

      } finally {
        if (inputStream != null) {
          inputStream.close();
        }
        if (outputStream != null) {
          outputStream.close();
        }
      }
    } catch (IOException e) {
      Log.i(TAG, "Error in download" + e.toString());
      return false;
    }
  }

但我从这个方法(writeResponseBodyToDisk)得到错误,错误为

文件正确下载时

java.net.SocketTimeoutException! 我觉得这个问题关于contentLength对我来说是-1。

感谢您的回答。

0 个答案:

没有答案