This article has been authorized “Liu Wangshu” wechat official account exclusive original release

preface

This article will directly use RxHttp library to realize file upload, download, download breakpoint, progress monitoring, not RxHttp to do too much explanation, if you do not understand RxHttp, please move on

RxHttp a chain to send a request, a new generation of Http request magic (1)

RxHttp a chain to send requests powerful data parsing capabilities (2)

RxHttp one chain send request powerful Param class (3)

RxHttp Generated API (4)

The purpose of this article is to introduce the RxHttp library to a wider audience. If you have read the above four articles, you can skip this article directly. Thank you for your support. 🙏 🙏.

upload

  RxHttp.postForm("http://...") // Send a Post request in the Form Form
        .add("key"."value")
        .add("file1".new File("xxx/1.png")) // Add a file object
        .add("file2".new File("xxx/2.png"))
        .asString() // the asXXX operator is an asynchronous operation
        .as(RxLife.asOnMain(this))  // Sense the life cycle and call back on the main thread
        .subscribe(s -> { 
            // Upload successfully, get the Http return value, the return value is String
        }, throwable -> {
            // Upload failed
        });
Copy the code

Note: If you need to parse Http returns, pass a Parser with the asParser operator

Upload with progress

Uploads with Progress use the asUpload(Progress,Scheduler) operator

  RxHttp.postForm("http://www.......") // Send a Post request in the Form Form
        .add("key1"."value1")// Add parameters, optional
        .add("file1".new File("xxx/1.png"))
        .asUpload(progress -> {
            // Upload progress callback,0-100, only when the progress is updated, up to 101 times, the last callback Http execution result
            int currentProgress = progress.getProgress(); // Current progress 0-100
            long currentSize = progress.getCurrentSize(); // The size of the bytes currently uploaded
            long totalSize = progress.getTotalSize();     // Total size of bytes to upload
        }, AndroidSchedulers.mainThread())// Specify the main thread callback
        .as(RxLife.as(this))  // Perceive the lifecycle
        .subscribe(s -> { //s is String, determined by the generics in the SimpleParser class
            // The upload is successful
        }, throwable -> {
            // Upload failed. Handle related logic
        });
Copy the code

Note: if you need to do to Http return values, can use asUpload (Parser, Progress, the Scheduler) method, passing a Parser Parser

download

  // File storage path
  String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
  RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")
        .asDownload(destPath) // Notice that the asDownload operator is used and the local path is passed in
        .as(RxLife.asOnMain(this))  // Sense the life cycle and call back on the main thread
        .subscribe(s -> {
            // Download successfully, callback file download path
        }, throwable -> {
            // Download failed
        });
Copy the code

Download with progress

With progress of the download using asDownload (String, Consumer, the Scheduler) method

  // File storage path
  String destPath = getExternalCacheDir() + "/" + System.currentTimeMillis() + ".apk";
  RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")
        .asDownload(destPath, progress -> {
            // Download progress callback,0-100, only when the progress has been updated, the maximum callback 101 times, the last callback file storage path
            int currentProgress = progress.getProgress(); // Current progress 0-100
            long currentSize = progress.getCurrentSize(); // The size of the bytes currently downloaded
            long totalSize = progress.getTotalSize();     // Total size of bytes to download
        }, AndroidSchedulers.mainThread()) // Specify the main thread callback
        .as(RxLife.as(this)) // Perceive the lifecycle
        .subscribe(s -> {//s is a String, where the file is stored
            // The download is complete
        }, throwable -> {
            // Failed to download the file
        });
Copy the code

Breakpoint downloading

The setRangeHeader method is used to pass in the start and end positions (the end position is not passed by default). There is no other difference

  String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";
  long length = new File(destPath).length(); // The length of the downloaded file
  RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")
        .setRangeHeader(length)  // Set the start download location, the default end location is the end of the file
        .asDownload(destPath)
        .as(RxLife.asOnMain(this)) // Add an observer to the perception lifecycle
        .subscribe(s -> { //s is a String
            Log.e("LJX"."breakpointDownloadAndProgress=" + s);
            // The download is successful
        }, throwable -> {
            // Failed to download the file
        });
Copy the code

Download with progress breakpoints

Download with progress breakpoint compared to download with progress, only call setRangeHeader method to pass in the start and end location (end location is not transmitted by default is the end of the file), there is no other difference

  String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";
  long length = new File(destPath).length(); // The length of the downloaded file
  RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")
        .setRangeHeader(length)  // Set the start download location, the default end location is the end of the file
        .asDownload(destPath, progress -> {
            // Download progress callback,0-100, only when progress is updated
            int currentProgress = progress.getProgress(); // Current progress 0-100
            long currentSize = progress.getCurrentSize(); // The size of the bytes currently downloaded
            long totalSize = progress.getTotalSize();     // Total size of bytes to download
        }, AndroidSchedulers.mainThread()) // Specify the main thread callback
        .as(RxLife.as(this)) // Add an observer to the perception lifecycle
        .subscribe(s -> { //s is a String
            // The download is successful
        }, throwable -> {
            // Failed to download the file
        });
Copy the code

Note: the above schedule breakpoint downloading, return schedule will start from 0, if you need to join the last time the progress of the download is called asDownload (String, long, Consumer, the Scheduler) method is introduced into the last have downloaded good length (the second parameter), as follows:

  String destPath = getExternalCacheDir() + "/" + "Miaobo.apk";
  long length = new File(destPath).length(); // The length of the downloaded file
  RxHttp.get("http://update.9158.com/miaolive/Miaolive.apk")
        .setRangeHeader(length)  // Set the start download location, the default end location is the end of the file
        .asDownload(destPath, length, progress -> {
            // Download progress callback,0-100, only when progress is updated
            int currentProgress = progress.getProgress(); // Current progress 0-100
            long currentSize = progress.getCurrentSize(); // The size of the bytes currently downloaded
            long totalSize = progress.getTotalSize();     // Total size of bytes to download
        }, AndroidSchedulers.mainThread()) // Specify the main thread callback
        .as(RxLife.as(this)) // Add an observer to the perception lifecycle
        .subscribe(s -> { //s is a String
            // The download is successful
        }, throwable -> {
            // Failed to download the file
        });
Copy the code

Multitasking download

We can use the RxJava merge operator as follows:

List<Observable<String>> downList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
    String destPath = getExternalCacheDir() + "/" + i + ".apk";
    String url = "http://update.9158.com/miaolive/Miaolive.apk"
    Observable<String> down = RxHttp.get(url)
            .asDownload(destPath);
    downList.add(down);
}

// Multi-task parallel download via RxJava internal thread pool
Observable.merge(downList)
        .as(RxLife.as(this))
        .subscribe(s -> {
            // Single task download completed
        }, throwable -> {
            // Download error}, () - > {// All tasks have been downloaded
        });

Copy the code

If you want to monitor the download progress of each task, it is also easy to use the old method, as follows:

List<Observable<String>> downList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
    String destPath = getExternalCacheDir() + "/" + i + ".apk";
    String url = "http://update.9158.com/miaolive/Miaolive.apk"
    Observable<String> down = RxHttp.get(url)
            .asDownload(destPath, progress -> {
                // Single download task progress callback
            }, AndroidSchedulers.mainThread())
    downList.add(down);
}

// Multi-task parallel download via RxJava internal thread pool
Observable.merge(downList)
        .as(RxLife.as(this))
        .subscribe(s -> {
            // Single task download completed
        }, throwable -> {
            // Download error}, () - > {// All tasks have been downloaded
        });

Copy the code

Multitask upload

The same goes for multitasking downloading.

summary

Well, file upload, download related to the introduction here, to this you will find, whether upload or download, progress monitoring are extremely similar, greatly reduce the cost of learning. How’s that? Is not very elegant, welcome to hit the face!!

Finally, much of the credit goes to the power of RxJava, thanks to RxJava and hats off to !!!!

The next article will continue to use RxJava’s powerful operators to see how it interacts with RxHttp. Reprint please indicate the source, thank you 🙏