我正在使用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。
感谢您的回答。