Square 的 OkHttp。下载进度

问题描述 投票:0回答:4

使用square`s OkHttp时有没有办法获取下载文件进度?

我在Recipes中没有找到任何解决方案。

他们有类Call,可以异步获取内容,但没有方法获取当前进度。

android android-networking okhttp
4个回答
31
投票

哎呀,答案很明显。抱歉问了个愚蠢的问题。只需要照常读取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");
    }
}

9
投票

您可以使用 okHttp 接收:Progress.java


0
投票

您可以使用 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
});

-1
投票

每次在 while 循环中,你都会发布进度。所以就像被阻塞了

© www.soinside.com 2019 - 2024. All rights reserved.