哎呀,答案很明显。抱歉问了个愚蠢的问题。只需要照常读取InputStream即可。
private class AsyncDownloader extends AsyncTask<Void, Long, Boolean> {
private final String URL = "file_url";
@Override
protected Boolean doInBackground(Void... params) {
OkHttpClient httpClient = new OkHttpClient();
Call call = httpClient.newCall(new Request.Builder().url(URL).get().build());
try {
Response response = call.execute();
if (response.code() == 200) {
InputStream inputStream = null;
try {
inputStream = response.body().byteStream();
byte[] buff = new byte[1024 * 4];
long downloaded = 0;
long target = response.body().contentLength();
publishProgress(0L, target);
while (true) {
int readed = inputStream.read(buff);
if(readed == -1){
break;
}
//write buff
downloaded += readed;
publishProgress(downloaded, target);
if (isCancelled()) {
return false;
}
}
return downloaded == target;
} catch (IOException ignore) {
return false;
} finally {
if (inputStream != null) {
inputStream.close();
}
}
} else {
return false;
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
@Override
protected void onProgressUpdate(Long... values) {
progressBar.setMax(values[1].intValue());
progressBar.setProgress(values[0].intValue());
textViewProgress.setText(String.format("%d / %d", values[0], values[1]));
}
@Override
protected void onPostExecute(Boolean result) {
textViewStatus.setText(result ? "Downloaded" : "Failed");
}
}
您可以使用 okHttp 接收:Progress.java
您可以使用 OkHttp + Okio:
Request.Builder requestBuilder = new Request.Builder();
okHttpClient.newCall(requestBuilder.url(downloadUrl).build()).enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {e.printStackTrace();}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
if(response.isSuccessful()){
BufferedSink sink=null; BufferedSource source=null;
try {
ResponseBody responseBody = response.body();assert responseBody != null;
long totalSize = responseBody.contentLength();
source = responseBody.source();
File downloadFile = new File(filePath);
sink = Okio.buffer(Okio.sink(downloadFile));
int bufferSize = 8 * 1024;
long downloadedSize = 0;
for (long bytesRead; (bytesRead = source.read(sink.getBuffer(), bufferSize)) != -1; ) {
sink.emit(); downloadedSize+=bytesRead; publishProgress(downloadedSize*100/totalSize);
}
Log.d(TAG, "File successfully downloaded and saved to storage.");
}
catch (IOException e){e.printStackTrace();}
finally {
try {if(sink!=null) {sink.flush();sink.close();} if(source != null)source.close();}catch (IOException e){e.printStackTrace();}
}
}
}
});
如果你想更新 UI,请在主线程上进行:
Handler handler = new Handler(Looper.getMainLooper());
handler.post(()-> {
publishProgress(); //do UI stuff
});
每次在 while 循环中,你都会发布进度。所以就像被阻塞了