基于Retrofit+Rxjava实现带进度显示的下载文件

时间:2022-08-30 19:30:51

本文实例为大家分享了retrofit rxjava实现下载文件的具体代码,供大家参考,具体内容如下

本文采用 :retrofit + rxjava

1.引入:

?
1
2
3
4
5
6
7
8
//rxjava
 compile 'io.reactivex:rxjava:latest.release'
 compile 'io.reactivex:rxandroid:latest.release'
 //network - squareup
 compile 'com.squareup.retrofit2:retrofit:latest.release'
 compile 'com.squareup.retrofit2:adapter-rxjava:latest.release'
 compile 'com.squareup.okhttp3:okhttp:latest.release'
 compile 'com.squareup.okhttp3:logging-interceptor:latest.release'

2.增加下载进度监听:

?
1
2
3
public interface downloadprogresslistener {
 void update(long bytesread, long contentlength, boolean done);
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
   }
  };
 
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
 }
}

3.创建下载进度的元素类:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public class download implements parcelable {
 
 private int progress;
 private long currentfilesize;
 private long totalfilesize;
 
 public int getprogress() {
  return progress;
 }
 
 public void setprogress(int progress) {
  this.progress = progress;
 }
 
 public long getcurrentfilesize() {
  return currentfilesize;
 }
 
 public void setcurrentfilesize(long currentfilesize) {
  this.currentfilesize = currentfilesize;
 }
 
 public long gettotalfilesize() {
  return totalfilesize;
 }
 
 public void settotalfilesize(long totalfilesize) {
  this.totalfilesize = totalfilesize;
 }
 
 @override
 public int describecontents() {
  return 0;
 }
 
 @override
 public void writetoparcel(parcel dest, int flags) {
  dest.writeint(this.progress);
  dest.writelong(this.currentfilesize);
  dest.writelong(this.totalfilesize);
 }
 
 public download() {
 }
 
 protected download(parcel in) {
  this.progress = in.readint();
  this.currentfilesize = in.readlong();
  this.totalfilesize = in.readlong();
 }
 
 public static final parcelable.creator<download> creator = new parcelable.creator<download>() {
  @override
  public download createfromparcel(parcel source) {
   return new download(source);
  }
 
  @override
  public download[] newarray(int size) {
   return new download[size];
  }
 };
}

4.下载文件网络类:

?
1
2
3
4
5
6
public interface downloadservice {
 
 @streaming
 @get
 observable<responsebody> download(@url string url);
}

注:这里@url是传入完整的的下载url;不用截取

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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);
 }
 
 
}

然后就是调用了:

该网络是在service里完成的

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class downloadservice extends intentservice {
 private static final string tag = "downloadservice";
 
 private notificationcompat.builder notificationbuilder;
 private notificationmanager notificationmanager;
 
 
 private string apkurl = "http://download.fir.im/v2/app/install/595c5959959d6901ca0004ac?download_token=1a9dfa8f248b6e45ea46bc5ed96a0a9e&source=update";
 
 public downloadservice() {
  super("downloadservice");
 }
 
 @override
 protected void onhandleintent(intent intent) {
  notificationmanager = (notificationmanager) getsystemservice(context.notification_service);
 
  notificationbuilder = new notificationcompat.builder(this)
    .setsmallicon(r.mipmap.ic_download)
    .setcontenttitle("download")
    .setcontenttext("downloading file")
    .setautocancel(true);
 
  notificationmanager.notify(0, notificationbuilder.build());
 
  download();
 }
 
 private void download() {
  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) {
 
   }
  });
 }
 
 private void downloadcompleted() {
  download download = new download();
  download.setprogress(100);
  sendintent(download);
 
  notificationmanager.cancel(0);
  notificationbuilder.setprogress(0, 0, false);
  notificationbuilder.setcontenttext("file downloaded");
  notificationmanager.notify(0, notificationbuilder.build());
 }
 
 private void sendnotification(download download) {
 
  sendintent(download);
  notificationbuilder.setprogress(100, download.getprogress(), false);
  notificationbuilder.setcontenttext(
    stringutils.getdatasize(download.getcurrentfilesize()) + "/" +
      stringutils.getdatasize(download.gettotalfilesize()));
  notificationmanager.notify(0, notificationbuilder.build());
 }
 
 private void sendintent(download download) {
 
  intent intent = new intent(mainactivity.message_progress);
  intent.putextra("download", download);
  localbroadcastmanager.getinstance(downloadservice.this).sendbroadcast(intent);
 }
 
 @override
 public void ontaskremoved(intent rootintent) {
  notificationmanager.cancel(0);
 }
}

mainactivity代码:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class mainactivity extends appcompatactivity {
 
 public static final string message_progress = "message_progress";
 
 private appcompatbutton btn_download;
 private progressbar progress;
 private textview progress_text;
 
 
 private broadcastreceiver broadcastreceiver = new broadcastreceiver() {
  @override
  public void onreceive(context context, intent intent) {
 
   if (intent.getaction().equals(message_progress)) {
 
    download download = intent.getparcelableextra("download");
    progress.setprogress(download.getprogress());
    if (download.getprogress() == 100) {
 
     progress_text.settext("file download complete");
 
    } else {
 
     progress_text.settext(stringutils.getdatasize(download.getcurrentfilesize())
       +"/"+
       stringutils.getdatasize(download.gettotalfilesize()));
 
    }
   }
  }
 };
 
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  btn_download = (appcompatbutton) findviewbyid(r.id.btn_download);
  progress = (progressbar) findviewbyid(r.id.progress);
  progress_text = (textview) findviewbyid(r.id.progress_text);
 
  registerreceiver();
 
  btn_download.setonclicklistener(new view.onclicklistener() {
   @override
   public void onclick(view view) {
    intent intent = new intent(mainactivity.this, downloadservice.class);
    startservice(intent);
   }
  });
 }
 
 private void registerreceiver() {
 
  localbroadcastmanager bmanager = localbroadcastmanager.getinstance(this);
  intentfilter intentfilter = new intentfilter();
  intentfilter.addaction(message_progress);
  bmanager.registerreceiver(broadcastreceiver, intentfilter);
 
 }
}

本文源码:retrofit rxjava实现下载文件

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/a1018875550/article/details/51832700