基于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实现下载文件
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。