Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to download the download from breakpoint based on Ok+Rxjava+retrofit

2025-03-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

How to download based on Ok+Rxjava+retrofit breakpoint continuation, I believe that many inexperienced people do not know what to do. Therefore, this paper summarizes the causes and solutions of the problem. Through this article, I hope you can solve this problem.

For everyone to share the breakpoint download of the specific code, for your reference, the specific content is as follows

1. Continue downloading of breakpoint based on Ok+Rxjava

2. Continue downloading of breakpoint based on Ok+Rxjava+Retrofit

The last blog introduced the implementation of breakpoint continuation download based on Ok+Rxjava. This article introduces the implementation of breakpoint continuation download based on Ok+Rxjava+Retrofit, demo download address, and the effect picture is the same as the previous picture, .

Let's talk about my general idea (slightly different from the previous article): according to the file download url, generate the file name according to the rules defined by yourself, and determine whether the file exists in the same path locally. If so, if the file size is the same as the file size obtained on the server, overwrite the local file and download it again. If the file is smaller than the file obtained by the server, the breakpoint download is performed, starting at the local file length. If the file does not exist, the download starts at 0 bytes.

Another difference is that we need to re-ResponseBody the source () method, where we monitor the progress of the file download, and then set our re-DownloadResponseBody through our custom Downloadinterceptor to complete our progress monitoring work.

Here is the main code:

Rewrite ResponseBody first

Public class DownloadResponseBody extends ResponseBody {private ResponseBody responseBody; / / Progress callback API private DownFileCallback downFileCallback; private BufferedSource bufferedSource; private String downUrl; public DownloadResponseBody (ResponseBody responseBody, DownFileCallback downFileCallback, String downUrl) {this.responseBody = responseBody; this.downFileCallback = downFileCallback; this.downUrl = downUrl;} @ 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; File file = new File (DownloadManager.getInstance (). GetTemporaryName (downUrl)); @ Override public long read (Buffer sink, long byteCount) throws IOException {long bytesRead = super.read (sink, byteCount); totalBytesRead + = bytesRead! =-1? BytesRead: 0; if (null! = downFileCallback) {if (bytesRead! =-1) {long loacalSize = file.length (); / / the length downloaded locally long trueTotal = loacalSize + responseBody.contentLength ()-the true length of the totalBytesRead;// file downFileCallback.onProgress (trueTotal,loacalSize);} else {}} return bytesRead;};}}

Rewrite Interceptor

Public class Downloadinterceptor implements Interceptor {private DownFileCallback downFileCallback; private String downUrl; public Downloadinterceptor (DownFileCallback listener,String downUrl) {this.downFileCallback = listener; this.downUrl = downUrl;} @ Override public Response intercept (Chain chain) throws IOException {Response response = chain.proceed (chain.request ()); return response.newBuilder () .body (new DownloadResponseBody (response.body (), downFileCallback,downUrl)) .build ();}}

And then our service

Public interface HttpService {/ * large files need to be judged by Streaming to prevent oom*/ @ Streaming @ GET Observable download (@ Header ("range") String start, @ Url String url) from being written to memory during the download process;}

Next, the download method in our DownloadManager

/ * start downloading * @ param url download address * @ param downFileCallback Progress callback API * / public void download (final String url, final DownFileCallback downFileCallback) {/ * downloading without processing * / if (url = = null | | submap.get (url)! = null) {return;} Downloadinterceptor interceptor = new Downloadinterceptor (downFileCallback, url); okHttpClient = new OkHttpClient.Builder () .addInterceptor (interceptor) .build () Retrofit retrofit = new Retrofit.Builder () .client (okHttpClient) .baseUrl ("http://imtt.dd.qq.com") .addCallAdapterFactory (RxJava2CallAdapterFactory.create ()) .build (); final HttpService httpservice = retrofit.create (HttpService.class); ProgressDownSubscriber subscriber = Observable.just (url) .flatMap (new Function () {@ Override public ObservableSource apply (String s) throws Exception {return Observable.just (createDownInfo (s) }) .map (new Function () {@ Override public DownloadInfo apply (DownloadInfo s) throws Exception {return getRealFileName (s);}}) .flatMap (new Function () {@ Override public Observable apply (DownloadInfo downInfo) throws Exception {return httpservice.download ("bytes=" + downInfo.getProgress () + "-", downInfo.getUrl ());}) / / download .map (new Function () {@ Override public DownloadInfo apply (ResponseBody responsebody) {try {return writecache (responsebody, url)) } catch (IOException e) {/ / * failed to throw an exception * / / e.printStackTrace ();} return null;}}) .subscrieOn (AndroidSchedulers.mainThread ()) / callback on the main thread .subscribeOn (Schedulers.io ()) / / execute on child threads .subscribeWith (new ProgressDownSubscriber () {@ Override public void onNext (DownloadInfo downInfo) {downFileCallback.onSuccess (downInfo); submap.remove (downInfo.getUrl () } @ Override public void onError (Throwable t) {downFileCallback.onFail (t.getMessage (); submap.remove (url);}}); submap.put (url, subscriber);}

Then pause the operation:

/ * suspend download * / public void stop (String url) {if (url = = null) return; if (submap.containsKey (url)) {ProgressDownSubscriber subscriber = submap.get (url); subscriber.dispose (); submap.remove (url);}}

Get the file length from the server

/ * get the file length from the server * * @ param downloadUrl * @ return * / private long getContentLength (String downloadUrl) {Request request = new Request.Builder () .url (downloadUrl) .build (); try {Response response = mClient.newCall (request). Execute (); if (response! = null & & response.isSuccessful ()) {long contentLength = response.body (). ContentLength (); response.close (); return contentLength = = 0? DownloadInfo.TOTAL_ERROR: contentLength;}} catch (IOException e) {e.printStackTrace ();} return DownloadInfo.TOTAL_ERROR;}

When getting the file length from the server, note that plaintext network transmission is prohibited after Android P, that is, above api 28. You need to declare "android:usesCleartextTraffic=" true in the application tag in your AndroidManifest to allow the application to transmit plaintext.

Usage: first of all, you need to obtain the permission of SD card.

DownloadManager.getInstance () .downloadPath (local storage address) .download (url1, new DownFileCallback () {@ Override public void onSuccess (DownloadInfo info) {Toast.makeText (MainActivity.this, url1 + "download completed", Toast.LENGTH_SHORT) .show ();} @ Override public void onFail (String msg) {Toast.makeText (MainActivity.this, url1 + "download failed", Toast.LENGTH_SHORT) .download () } @ Override public void onProgress (final long totalSize, final long downSize) {/ / it should be noted that if the total size of the file is 50m and the downloaded size is 10m, / / when downloading again, the totalSize returned by onProgress is the total length of the file / / minus the downloaded size of 10m, that is, 40MMagneDownSize is the downloaded quantity of this download / / the good news is, I have already done some internal processing, so feel free to use it. But we still need to know about runOnUiThread (new Runnable () {@ Override public void run () {int progress = (int) (downSize * 100 / totalSize)). Progress1.setProgress (progress);}})

All right, that's all for today. I hope I can help you all. This is also a kind of impressive note for me.

After reading the above, have you mastered how to download the download at the breakpoint based on Ok+Rxjava+retrofit? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report