After reading several articles on rxjava and retrofit on the Internet, I probably have a preliminary understanding that I just need to do a multi-picture upload function, so I will use it to perform the operation. The following content will be based on the similarities and differences between the previous implementation method and the implementation using rxjava. If you don’t like it when you write notes for the first time, you will be criticized.
Upload multiple pictures on the normal version
Since mobile phone photos are usually several meters in size, if you don’t do it, you will upload them directly. I will smile and say nothing (give me a look and feel it yourself). Therefore, uploading is divided into two steps: compressing the image and requesting upload. Please see the pseudo-code below (PS: I can’t write the background myself, and the project background cannot be used, so I can only give pseudo-code)
//Picture CollectionList<String> imgs = new ArrayList<>(); //Compressed image path collectionList<String> tmpImgs = new ArrayList<>(); Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { (msg); //TODO calls network request upload after receiving the message } }; public void compressImages() { new Thread(new Runnable() { @Override public void run() { for (String path : imgs) { //TODO calls the method of compressing the picture, and save it in a temporary folder after compression. ("Compressed Path"); } (0); } }).start(); }
Do you think it’s very troublesome after reading it? Well, maybe it’s just a trouble for me to implement it. It is said that the logical chain will become clearer after using rxjava. Let’s see if this is the case. Please see the pseudocode after using rxjava:
@Multipart @POST("your address") Observable<String> uploadImgs(@PartMap Map<String, RequestBody> map, @Part("imgs") MultipartBody body); //Define a request interface first. In addition to the image, there may be some other parameters that need to be uploaded, so a map is also defined. Next, start the main text: public void upload() { final Map<String, RequestBody> map = new HashMap<>(); ("userId", (("form-data"),"1"); final builder = new (); (imgs) .map(new Func1<String, String>() { @Override public String call(String path) { //Call the image compression and return the path after compression tmp_path //Note that Filedata is the corresponding field given to you by the background. ("Filedata", "", (, new File(tmp_path))); return path; } }).last() .flatMap(new Func1<String, Observable<String>>() { @Override public Observable<String> call(String path) { return (map, ()); } }) .subscribeOn(()) .observeOn(()) .subscribe(new Subscriber<String>() { @Override public void onCompleted() { } @Override public void onError(Throwable e) { //Error handling } @Override public void onNext(String res) { //Successful post-processing } }); }
1. First, define a map, which is used to upload other parameters. Why is the value of RequestBody type? Isn't it enough to use String? Why are you pretending to be stupid? Well, I thought so at first, but the value transmitted to the server comes with a ‘’ bonus. The 1 was transferred to the past and became ‘1’. I was planning to talk to the backend seriously, but I found that this was what I uploaded (blushing). Then I found that if the annotated with @part is not used, the "' will be automatically added. I don't know why this is so far. Please explain your doubts if you understand it.
2. Then, as the name implies, multiple RequestBody can be added to add multiple images. Okay, the train is about to start.
3. Let’s briefly talk about what the next large piece of code is for, of course, based on what you already understand the from, map, flatmap, and last of rxjava are used for.
a. From will split the imgs collection into a single String and send it out
b. The function of map is to compress the image here and add the compressed image to it, which is equivalent to compressing the image for loop.
c. Here, flatmap, success or failure has taken another hit. There is a conversion here. Note that the String returned after map processing is still a String type. After flatmap, it will be converted into Observable<String>, which is the result returned after uploading the image.
d. Okay, so far, it seems that we have achieved the function of uploading images in one link. It feels like it needs to be clearer (if not, then I'm still trying to do anything). Alas, don't leave, what the hell is it that you ignore last?
e. If you don’t add the last method after the map, you can give it a try to ensure that the background will turn your eyes to the sky. Since from is sent one by one, each object will call the uploadImgs method once in flatmap, which is definitely not possible. After adding the last method, it will only send the last object of the sequence sent from the map, which ensures that all images are compressed and added and then call the uploadImgs method, and it will only be called once.
The above are my small notes on uploading multiple pictures using rxjava + retrofit. I hope they will be helpful to everyone's learning and I hope everyone will support me more.