I have been learning RxJava for a while and have been thinking about how to use it and how to use it reasonably in my project. In many Android projects, image uploads exist. Below I will introduce how to upload multiple images asynchronously using Rxjava.
1. The frame used
compile ':Luban:1.0.9'//Picture compression compile ':xutils:3.3.34'//Network request compile ':rxandroid:1.1.0'//rxandroid compile ':rxjava:1.1.0'//rxjava
In addition, Rxjava is very consistent with Lambda expressions, so it introduces Lambda configuration. It is necessary to support the features of java8 in gradle:
jackOptions { enabled true } compileOptions { targetCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8 }
Initialize the configuration, you need to initialize the network request framework in the onCreate of your own Application. Negative will make the network request impossible.
public class APP extends Application { private static APP instance; public static synchronized APP getInstance() { return instance; } @Override public void onCreate() { (); (this); (); instance = this; } }
2. Picture compression and upload
Here, in order to demonstrate usage and image upload is just a simulation request, three arrays are manually created to cache the image selected and processed URLs.
private List<String> mImageList; private List<String> mReduceImageList; private List<String> mImageUrl; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); mImageUrl = new ArrayList<>(); mImageList = new ArrayList<>(); mReduceImageList = new ArrayList<>(); ("content://media/external/images/media/573778"); ("content://media/external/images/media/573778"); ("content://media/external/images/media/573778"); Button button = (Button) findViewById(.button1); (v -> setImage()); }
Most of the uploads of pictures are based on multiple Uri addresses selected based on the photo or gallery. If not compressed, the pictures are very large. Generally, the pictures taken have hundreds of KB or several M. Therefore, in order to save the load on the traffic and the server, compression is required. The compressed image size is only about a few dozen KB.
/** * Search location pictures according to URI * * @param selectedImage */ private void sendPicByUri(Uri selectedImage) { Cursor cursor = getContentResolver().query(selectedImage, null, null, null, null); String st8 = "No picture found"; if (cursor != null) { (); int columnIndex = ("_data"); String picturePath = (columnIndex); (); if (picturePath == null || ("null")) { Toast toast = (this, st8, Toast.LENGTH_SHORT); (, 0, 0); (); return; } sendPicture(picturePath); } else { File file = new File(()); if (!()) { Toast toast = (this, st8, Toast.LENGTH_SHORT); (, 0, 0); (); return; } sendPicture(()); } } /** * Compressed pictures * * @param filePath */ private void sendPicture(final String filePath) { (tag, "Compressed Pictures"); Luban .get(this) .load(new File(filePath)) .putGear(Luban.THIRD_GEAR) .setCompressListener(new OnCompressListener() { @Override public void onStart() { } @Override public void onSuccess(File file) { (tag, "Compressed pictures==》"); uploadImg(file); } @Override public void onError(Throwable e) { } }) .launch(); setResult(RESULT_OK); }
In order to optimize the code and RxJava used for these time-consuming operations and perform asynchronous processing, we need to create the RxJava writing method:
/** * Distribute url recipient */ private Func1<List<String>, Observable<String>> mOneLetterFunc = Observable::from; private Action1<String> mImageUrlAction = s -> uploadImg(new File(s)); private Action1<String> mAddContent = s -> sendPicByUri((s)); /** * Distribute compressed images */ private void setImage() { (tag, "Start distribution of acquired urls"); (mImageList) .subscribeOn(()) // Specify subscribe() to occur in IO thread .observeOn(()) .flatMap(mOneLetterFunc) .subscribe(mAddContent); }
The distributed colleagues will make asynchronous network requests, upload pictures to the server, and return the URL image address stored by the server:
/** * Image upload server * * @param file file */ public void uploadImg(File file) { (tag, "Online request to upload pictures"); RequestParams params = new RequestParams("This is the Http address uploaded to the server"); ("imgContent", file); (true); ().post(params, new <String>() { @Override public void onWaiting() { } @Override public void onStarted() { } @Override public void onLoading(long total, long current, boolean isDownloading) { } @Override public void onSuccess(String result) { try { JSONObject jsonObject = new JSONObject(result); JSONObject data = ("data"); (("src")); if (() == ()) { ("Upload completed==", ()); } } catch (JSONException e) { (); } } @Override public void onError(Throwable ex, boolean isOnCallback) { ("An error occurred during upload==", ()); } @Override public void onCancelled(CancelledException cex) { } @Override public void onFinished() { } }); }
In order to save time, you can also perform operations such as compressing pictures when adding pictures. When uploading, only upload network operations are performed
/** * Upload selected pictures directly */ private void uploadingImage() { (tag, "Start uploading pictures"); if (() > 0) { (mReduceImageList) .subscribeOn(()) // Specify subscribe() to occur in IO thread .observeOn(()) .flatMap(mOneLetterFunc) .subscribe(mImageUrlAction); } }
Three, summary
Here is just a brief demonstration of the basic usage of Rxjava. It is unquestionable, but to use it well, you still need to learn it in depth. It also makes our code more concise. Learning is endless, thank you for providing us with so many useful frameworks.
The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.