In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly shows you "how to use Retrofit+RxJava to achieve file download with progress bar", the content is easy to understand, clear, hope to help you solve your doubts, the following let the editor lead you to study and learn "how to use Retrofit+RxJava to achieve file download with progress bar" this article.
Let's talk about version control first. the general practice is to obtain the app version number stored on the server through the interface, and compare it with the application version number. Update it if the version is lower. Let's take a look at how to obtain the application version number.
PackageManager packageManager = mActivity.getPackageManager (); PackageInfo packageInfo = null; try {packageInfo = packageManager.getPackageInfo (mActivity.getPackageName (), 0);} catch (PackageManager.NameNotFoundException e) {e.printStackTrace ();} String versionName = packageInfo.versionName
You can see that the getPackageManager method in Context is used to get the PackageManager object, which can be used to get some information about the version.
The above belongs to the attached content, and then there is the function of downloading the progress bar in Retrofit+RxJava. Retrofit itself does not provide the function of displaying the progress bar, but Retrofit uses Okhttp for network requests by default. Here, you can customize the interceptor to intercept and achieve the progress. The Demo of Okhttp also provides us with a code. If you need it, you can refer to Progress.javar to see the settings of the interceptor:
Public class ProgressResponseBody extends ResponseBody {private ResponseBody responseBody; private ProgressListener progressListener; private BufferedSource bufferedSource; public ProgressResponseBody (ResponseBody responseBody,ProgressListener 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 {/ / current read bytes long bytesRead = super.read (sink, byteCount); / / increase the number of bytes currently read. If the read is completed, bytesRead will return-1 totalBytesRead + = bytesRead! =-1? BytesRead: 0; / / callback. If contentLength () does not know the length, it returns-1 progressListener.onProgress (totalBytesRead,responseBody.contentLength (), bytesRead,bytesRead==-1); return bytesRead;}};}}
ProgressListener is used to listen for progress changes. Callback to ProgressInterceptor. ProgressInterceptor is a custom interceptor. You can take a look at the code.
Public class ProgressInterceptor implements Interceptor {@ Override public Response intercept (Chain chain) throws IOException {Response response=chain.proceed (chain.request ()); return response.newBuilder () .body (new ProgressResponseBody (response.body (), progressListener)) .build ();} static final ProgressListener progressListener=new ProgressListener () {@ Override public void onProgress (long progress, long total, long speed, boolean done) {Log.i ("log", "progress=" + progress+ "total=" + total);}
To make it easier to get progress, you can add a custom interceptor directly through the addNetworkInterceptor method of OkHttpClient, for example:
/ / set interceptor OkHttpClient client = new OkHttpClient.Builder () .addNetworkInterceptor for Okhttp (new Interceptor () {@ Override public Response intercept (Chain chain) throws IOException {Response originalResponse = chain.proceed (chain.request ()); return originalResponse.newBuilder () .body (new ProgressResponseBody (originalResponse.body (), progressListener)) .build ();}) .build () / / Progress callback listening ProgressListener progressListener=new ProgressListener () {@ Override public void onProgress (long progress, long total, long speed, boolean done) {Message message=new Message (); message.obj=new AmallLoadBean (progress,total); progressHandler.sendMessage (message);}}
Here, we create a ProgressHandler static inner class inherited from Handler to refresh the progress in the main thread. By the way, static is used to modify ProgressHandler because the static inner class does not hold references to external class objects by default. You need to pay attention to the memory leak of Handler and use the following words:
/ / process the download version progress public class ProgressHandler extends Handler {private WeakReference mActivityWeakReference; public ProgressHandler (Activity activity) {mActivityWeakReference=new WeakReference (activity);} @ Override public void handleMessage (Message msg) {if (mActivityWeakReference.get ()! = null) {AmallLoadBean amallLoadBean= (AmallLoadBean) msg.obj; long progress=amallLoadBean.getProgress (); long total=amallLoadBean.getTotal (); float cp= (float) progress/ (float) total;}
Going back to the download file, I used the Retrofit+RxJava method to implement it. Before writing it, I also read what others wrote. It seems to be incomplete. Xiaman also encountered some small pits. Let's talk about it:
Observable.subscribeOn (Schedulers.io ()) .subscrieOn (Schedulers.io ()) .doOnNext (new Action1 () {@ Override public void call (ResponseBody responseBody) {saveFiles (responseBody);}}) .subscrieOn (AndroidSchedulers.mainThread ()) .subscribe (new Observer () {@ Override public void onCompleted () {installApk ();} @ Override public void onError (Throwable e) {ToastUtils.getInstance (). ShowToast ("Please download the latest version in the application market") } @ Override public void onNext (ResponseBody responseBody) {}});}
The file is stored before the subscribe method through RxJava's doOnNext. Note here that the doOnNext method needs to be executed in the child thread, calling the .uploeOn (Schedulers.io ()) method, and then switching to the main thread, otherwise the file cannot be downloaded. When the file download is complete, execute the installApk () method in the onCompleted method to install app. It should be noted that permission adaptation needs to be done here, because mine is encapsulated by myself because I won't take it out. It's very simple to write it myself. The code to save the file has been released to everyone, in popular language:
/ * Save file * / public void saveFiles (ResponseBody responseBody) {InputStream inputStream= null; FileOutputStream fileOutputStream= null; byte [] buffer=new byte [2048]; int len; File file=new File (saveFileName); if (! file.exists ()) {file.mkdirs ();} try {inputStream=responseBody.byteStream (); fileOutputStream=new FileOutputStream (file); while ((len=inputStream.read (buffer))! =-1) {fileOutputStream.write (buffer,0,len);} inputStream.close (); fileOutputStream.close () } catch (Exception e) {e.printStackTrace ();}}
When installing files, you need to pay attention to the adaptation after 7.0. just look at the code, and the principle of photo adaptation has always been a problem of Android's permission to private files.
/ * install apk * * / private void installApk () {File apkfile = new File (saveFileName); if (! apkfile.exists ()) {return;} / / determine version number if (Build.VERSION.SDK_INT > = Build.VERSION_CODES.N) {Uri apkUri = FileProvider.getUriForFile (activity, "* .fileprovider", apkfile); Intent install = new Intent (Intent.ACTION_VIEW); install.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK) / / add this sentence to the target application to temporarily authorize the file represented by the Uri install.addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION); install.setDataAndType (apkUri, "application/vnd.android.package-archive"); activity.startActivity (install);} else {Intent I = new Intent (Intent.ACTION_VIEW); i.setDataAndType (Uri.parse ("file://" + apkfile.toString ())," application/vnd.android.package-archive "); activity.startActivity (I) }}
The above is all the contents of the article "how to use Retrofit+RxJava to download files with progress bars". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.