Android 通过改装2异步下载时是否可以显示进度条? @流媒体 @得到 调用downloadSong(@Url字符串Url);
上面的代码用于使用改型异步下载文件。我想知道下载的进度,如果有暂停/恢复的可能,也请回答这个问题。最后我得到了答案 为此,我们需要在改型的同时使用rxjava 下载ProgressListener.javaAndroid 通过改装2异步下载时是否可以显示进度条? @流媒体 @得到 调用downloadSong(@Url字符串Url);,android,download,retrofit,retrofit2,progress,Android,Download,Retrofit,Retrofit2,Progress,上面的代码用于使用改型异步下载文件。我想知道下载的进度,如果有暂停/恢复的可能,也请回答这个问题。最后我得到了答案 为此,我们需要在改型的同时使用rxjava 下载ProgressListener.java @Streaming @GET Call<ResponseBody> downloadSong(@Url String url); 下载ProgressResponseBody.java public interface DownloadProgressListener {
@Streaming
@GET
Call<ResponseBody> downloadSong(@Url String url);
下载ProgressResponseBody.java
public interface DownloadProgressListener {
void update(long bytesRead, long contentLength, boolean done);
}
下载ProgressInterceptor.java
public class DownloadProgressResponseBody extends ResponseBody {
private ResponseBody responseBody;
private DownloadProgressListener progressListener;
private BufferedSource bufferedSource;
public DownloadProgressResponseBody(ResponseBody responseBody,
DownloadProgressListener progressListener) {
this.responseBody = responseBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() {
return responseBody.contentLength();
}
@Override
public BufferedSource source() {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
if (null != progressListener) {
progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
}
return bytesRead;
}
};
}
}
下载.java
public class DownloadProgressInterceptor implements Interceptor {
private DownloadProgressListener listener;
public DownloadProgressInterceptor(DownloadProgressListener listener) {
this.listener = listener;
}
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new DownloadProgressResponseBody(originalResponse.body(), listener))
.build();
}
}
我只是使用代码@Jan post,但我遇到了一个问题,它没有下载,只能得到一次回调,经过多次尝试,我找到了解决方案:
DownloadProgressListener listener = new DownloadProgressListener() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
Download download = new Download();
download.setTotalFileSize(contentLength);
download.setCurrentFileSize(bytesRead);
int progress = (int) ((bytesRead * 100) / contentLength);
download.setProgress(progress);
sendNotification(download);
}
};
File outputFile = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOWNLOADS), "file.apk");
String baseUrl = StringUtils.getHostName(apkUrl);
new DownloadAPI(baseUrl, listener).downloadAPK(apkUrl, outputFile, new Subscriber() {
@Override
public void onCompleted() {
downloadCompleted();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
downloadCompleted();
Log.e(TAG, "onError: " + e.getMessage());
}
@Override
public void onNext(Object o) {
}
});
只需将拦截器更改为networkInterceptor
而且运行正常!
祝你好运 因此,我正在通过rxjava教程来应用这种方法,希望您能获得一个很好的性能,可以上传多个通知的进度?@Bincy Baby请告诉我需要添加的所有依赖项。您必须将改装和rxjava 1添加到您的项目中。你能帮助我吗?如果您有新问题,请单击按钮提问。如果此问题有助于提供上下文,请包含指向此问题的链接。-谢谢你的建议,但这只是对Jan答案的补充,我想在Jan的答案下面添加评论,但我没有足够的声誉。
public interface DownloadService {
@Streaming
@GET
Observable<ResponseBody> download(@Url String url);
}
public class DownloadAPI {
private static final String TAG = "DownloadAPI";
private static final int DEFAULT_TIMEOUT = 15;
public Retrofit retrofit;
public DownloadAPI(String url, DownloadProgressListener listener) {
DownloadProgressInterceptor interceptor = new DownloadProgressInterceptor(listener);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
public void downloadAPK(@NonNull String url, final File file, Subscriber subscriber) {
Log.d(TAG, "downloadAPK: " + url);
retrofit.create(DownloadService.class)
.download(url)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.map(new Func1<ResponseBody, InputStream>() {
@Override
public InputStream call(ResponseBody responseBody) {
return responseBody.byteStream();
}
})
.observeOn(Schedulers.computation())
.doOnNext(new Action1<InputStream>() {
@Override
public void call(InputStream inputStream) {
try {
FileUtils.writeFile(inputStream, file);
} catch (IOException e) {
e.printStackTrace();
throw new CustomizeException(e.getMessage(), e);
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
}
DownloadProgressListener listener = new DownloadProgressListener() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
Download download = new Download();
download.setTotalFileSize(contentLength);
download.setCurrentFileSize(bytesRead);
int progress = (int) ((bytesRead * 100) / contentLength);
download.setProgress(progress);
sendNotification(download);
}
};
File outputFile = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOWNLOADS), "file.apk");
String baseUrl = StringUtils.getHostName(apkUrl);
new DownloadAPI(baseUrl, listener).downloadAPK(apkUrl, outputFile, new Subscriber() {
@Override
public void onCompleted() {
downloadCompleted();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
downloadCompleted();
Log.e(TAG, "onError: " + e.getMessage());
}
@Override
public void onNext(Object o) {
}
});
OkHttpClient client = new OkHttpClient.Builder()
// .addInterceptor(interceptor)
.addNetworkInterceptor(interceptor)