基于Retrofit+Rxjava实现带进度显示的下载文件
本文实例为大家分享了RetrofitRxjava实现下载文件的具体代码,供大家参考,具体内容如下
本文采用:retrofit+rxjava
1.引入:
//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.增加下载进度监听:
publicinterfaceDownloadProgressListener{
voidupdate(longbytesRead,longcontentLength,booleandone);
}
publicclassDownloadProgressResponseBodyextendsResponseBody{
privateResponseBodyresponseBody;
privateDownloadProgressListenerprogressListener;
privateBufferedSourcebufferedSource;
publicDownloadProgressResponseBody(ResponseBodyresponseBody,
DownloadProgressListenerprogressListener){
this.responseBody=responseBody;
this.progressListener=progressListener;
}
@Override
publicMediaTypecontentType(){
returnresponseBody.contentType();
}
@Override
publiclongcontentLength(){
returnresponseBody.contentLength();
}
@Override
publicBufferedSourcesource(){
if(bufferedSource==null){
bufferedSource=Okio.buffer(source(responseBody.source()));
}
returnbufferedSource;
}
privateSourcesource(Sourcesource){
returnnewForwardingSource(source){
longtotalBytesRead=0L;
@Override
publiclongread(Buffersink,longbyteCount)throwsIOException{
longbytesRead=super.read(sink,byteCount);
//read()returnsthenumberofbytesread,or-1ifthissourceisexhausted.
totalBytesRead+=bytesRead!=-1?bytesRead:0;
if(null!=progressListener){
progressListener.update(totalBytesRead,responseBody.contentLength(),bytesRead==-1);
}
returnbytesRead;
}
};
}
}
publicclassDownloadProgressInterceptorimplementsInterceptor{
privateDownloadProgressListenerlistener;
publicDownloadProgressInterceptor(DownloadProgressListenerlistener){
this.listener=listener;
}
@Override
publicResponseintercept(Chainchain)throwsIOException{
ResponseoriginalResponse=chain.proceed(chain.request());
returnoriginalResponse.newBuilder()
.body(newDownloadProgressResponseBody(originalResponse.body(),listener))
.build();
}
}
3.创建下载进度的元素类:
publicclassDownloadimplementsParcelable{
privateintprogress;
privatelongcurrentFileSize;
privatelongtotalFileSize;
publicintgetProgress(){
returnprogress;
}
publicvoidsetProgress(intprogress){
this.progress=progress;
}
publiclonggetCurrentFileSize(){
returncurrentFileSize;
}
publicvoidsetCurrentFileSize(longcurrentFileSize){
this.currentFileSize=currentFileSize;
}
publiclonggetTotalFileSize(){
returntotalFileSize;
}
publicvoidsetTotalFileSize(longtotalFileSize){
this.totalFileSize=totalFileSize;
}
@Override
publicintdescribeContents(){
return0;
}
@Override
publicvoidwriteToParcel(Parceldest,intflags){
dest.writeInt(this.progress);
dest.writeLong(this.currentFileSize);
dest.writeLong(this.totalFileSize);
}
publicDownload(){
}
protectedDownload(Parcelin){
this.progress=in.readInt();
this.currentFileSize=in.readLong();
this.totalFileSize=in.readLong();
}
publicstaticfinalParcelable.CreatorCREATOR=newParcelable.Creator(){
@Override
publicDownloadcreateFromParcel(Parcelsource){
returnnewDownload(source);
}
@Override
publicDownload[]newArray(intsize){
returnnewDownload[size];
}
};
}
4.下载文件网络类:
publicinterfaceDownloadService{
@Streaming
@GET
Observabledownload(@UrlStringurl);
}
注:这里@Url是传入完整的的下载URL;不用截取
publicclassDownloadAPI{
privatestaticfinalStringTAG="DownloadAPI";
privatestaticfinalintDEFAULT_TIMEOUT=15;
publicRetrofitretrofit;
publicDownloadAPI(Stringurl,DownloadProgressListenerlistener){
DownloadProgressInterceptorinterceptor=newDownloadProgressInterceptor(listener);
OkHttpClientclient=newOkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(DEFAULT_TIMEOUT,TimeUnit.SECONDS)
.build();
retrofit=newRetrofit.Builder()
.baseUrl(url)
.client(client)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
}
publicvoiddownloadAPK(@NonNullStringurl,finalFilefile,Subscribersubscriber){
Log.d(TAG,"downloadAPK:"+url);
retrofit.create(DownloadService.class)
.download(url)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.map(newFunc1(){
@Override
publicInputStreamcall(ResponseBodyresponseBody){
returnresponseBody.byteStream();
}
})
.observeOn(Schedulers.computation())
.doOnNext(newAction1(){
@Override
publicvoidcall(InputStreaminputStream){
try{
FileUtils.writeFile(inputStream,file);
}catch(IOExceptione){
e.printStackTrace();
thrownewCustomizeException(e.getMessage(),e);
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(subscriber);
}
}
然后就是调用了:
该网络是在service里完成的
publicclassDownloadServiceextendsIntentService{
privatestaticfinalStringTAG="DownloadService";
privateNotificationCompat.BuildernotificationBuilder;
privateNotificationManagernotificationManager;
privateStringapkUrl="http://download.fir.im/v2/app/install/595c5959959d6901ca0004ac?download_token=1a9dfa8f248b6e45ea46bc5ed96a0a9e&source=update";
publicDownloadService(){
super("DownloadService");
}
@Override
protectedvoidonHandleIntent(Intentintent){
notificationManager=(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder=newNotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_download)
.setContentTitle("Download")
.setContentText("DownloadingFile")
.setAutoCancel(true);
notificationManager.notify(0,notificationBuilder.build());
download();
}
privatevoiddownload(){
DownloadProgressListenerlistener=newDownloadProgressListener(){
@Override
publicvoidupdate(longbytesRead,longcontentLength,booleandone){
Downloaddownload=newDownload();
download.setTotalFileSize(contentLength);
download.setCurrentFileSize(bytesRead);
intprogress=(int)((bytesRead*100)/contentLength);
download.setProgress(progress);
sendNotification(download);
}
};
FileoutputFile=newFile(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_DOWNLOADS),"file.apk");
StringbaseUrl=StringUtils.getHostName(apkUrl);
newDownloadAPI(baseUrl,listener).downloadAPK(apkUrl,outputFile,newSubscriber(){
@Override
publicvoidonCompleted(){
downloadCompleted();
}
@Override
publicvoidonError(Throwablee){
e.printStackTrace();
downloadCompleted();
Log.e(TAG,"onError:"+e.getMessage());
}
@Override
publicvoidonNext(Objecto){
}
});
}
privatevoiddownloadCompleted(){
Downloaddownload=newDownload();
download.setProgress(100);
sendIntent(download);
notificationManager.cancel(0);
notificationBuilder.setProgress(0,0,false);
notificationBuilder.setContentText("FileDownloaded");
notificationManager.notify(0,notificationBuilder.build());
}
privatevoidsendNotification(Downloaddownload){
sendIntent(download);
notificationBuilder.setProgress(100,download.getProgress(),false);
notificationBuilder.setContentText(
StringUtils.getDataSize(download.getCurrentFileSize())+"/"+
StringUtils.getDataSize(download.getTotalFileSize()));
notificationManager.notify(0,notificationBuilder.build());
}
privatevoidsendIntent(Downloaddownload){
Intentintent=newIntent(MainActivity.MESSAGE_PROGRESS);
intent.putExtra("download",download);
LocalBroadcastManager.getInstance(DownloadService.this).sendBroadcast(intent);
}
@Override
publicvoidonTaskRemoved(IntentrootIntent){
notificationManager.cancel(0);
}
}
MainActivity代码:
publicclassMainActivityextendsAppCompatActivity{
publicstaticfinalStringMESSAGE_PROGRESS="message_progress";
privateAppCompatButtonbtn_download;
privateProgressBarprogress;
privateTextViewprogress_text;
privateBroadcastReceiverbroadcastReceiver=newBroadcastReceiver(){
@Override
publicvoidonReceive(Contextcontext,Intentintent){
if(intent.getAction().equals(MESSAGE_PROGRESS)){
Downloaddownload=intent.getParcelableExtra("download");
progress.setProgress(download.getProgress());
if(download.getProgress()==100){
progress_text.setText("FileDownloadComplete");
}else{
progress_text.setText(StringUtils.getDataSize(download.getCurrentFileSize())
+"/"+
StringUtils.getDataSize(download.getTotalFileSize()));
}
}
}
};
@Override
protectedvoidonCreate(BundlesavedInstanceState){
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(newView.OnClickListener(){
@Override
publicvoidonClick(Viewview){
Intentintent=newIntent(MainActivity.this,DownloadService.class);
startService(intent);
}
});
}
privatevoidregisterReceiver(){
LocalBroadcastManagerbManager=LocalBroadcastManager.getInstance(this);
IntentFilterintentFilter=newIntentFilter();
intentFilter.addAction(MESSAGE_PROGRESS);
bManager.registerReceiver(broadcastReceiver,intentFilter);
}
}
本文源码:RetrofitRxjava实现下载文件
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。