This is the 8th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
Leisure time to write out some insights, the length is longer, this article is the last one, you can see my home page to get the PDF version of the file
Application scenarios and usage of RxJava
1. Integration with Retrofit
Retrofit is a well-known web request library for Square. Those of you who haven’t used Retrofit can skip this section
I mean, every scenario I’ve given you is just an example, and there’s no context between the examples, it’s just a primer, so you
You can skip this and watch another scene.
Retrofit provides the traditional Callback API as well as the RxJava version of the Observable API. The following I
By way of comparison, the RxJava version of Retrofit’s API differs from the traditional version.
Take the interface to get a User object as an example. Using Retrofit’s traditional API, you can define requests like this:
@GET("/user")
public void getUser(@Query("userId") String userId, Callback<User> callback);
Copy the code
During application construction, Retrofit automatically implements methods and generates code so that developers can use the following methods
Get a specific user and process the response:
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling. }};Copy the code
Using the RXJava-style API, the same request is defined like this:
@GET("/user")
public Observable<User> getUser(@Query("userId") String userId);
Copy the code
Here’s how it works:
getUser(userId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling}});Copy the code
See the difference?
In RxJava form, Retrofit encapsulates the request into an Observable, which calls onNext() after the request, or after the request
OnError () is called on failure.
By contrast, the Callback form and Observable form look different, but they are similar in nature and detail
The Observable form seems to be worse than the Callback form. So why does Retrofit support RxJava?
Because it works! You can’t tell from this example because this is just the simplest case. And once the situation is complicated, Callback shape
The formula will soon start to be a headache. Such as:
Imagine a situation where the User fetched by your program should not be displayed directly, but should first be compared with data in the database
And correction after display. Callback: Callback Callback
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
processUser(user); // Try to correct User data
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling}};Copy the code
Any questions?
It’s easy, but don’t do it. Why is that? Because doing so can affect performance. Database operations are heavy and cost a read/write operation
10~20ms is common, and this time can easily lead to interface lag. So in general, avoid it if you can
Process the database in the main thread. So to improve performance, this code can be optimized:
getUser(userId, new Callback<User>() {
@Override
public void success(User user) {
new Thread() {
@Override
public void run() {
processUser(user); // Try to correct User data
runOnUiThread(new Runnable() { // Cut back to the UI thread
@Override
public void run(){ userView.setUser(user); }}); }).start(); } @Override publicvoid failure(RetrofitError error) {
// Error handling}};Copy the code
Performance issues resolved, but… This code is really too messy, the indented mystery ah! Messy code is often more than just an aesthetic problem because of the code
The more cluttered the project, the more difficult it is to read, and a project full of cluttered code will undoubtedly reduce the readability of the code, resulting in team development efficiency
Decrease and error rate increase.
At this point, if you use RxJava form, much easier to do. The code in RxJava form looks like this:
getUser(userId)
.doOnNext(new Action1<User>() {
@Override
public void call(User user) {
processUser(user);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling}});Copy the code
The background code and the foreground code are all in one chain, which is much clearer.
Another example: suppose the /user interface is not directly accessible, but needs to be filled in with a token obtained online. What does the code do
Write?
Callback method, which can be nested: @get ("/token")
public void getToken(Callback<String> callback);
@GET("/user")
public void getUser(@Query("token") String token, @Query("userId") String
userId, Callback<User> callback);
getToken(new Callback<String>() {
@Override
public void success(String token) {
getUser(token, userId, new Callback<User>() {
@Override
public void success(User user) {
userView.setUser(user);
}
@Override
public void failure(RetrofitError error) {
// Error handling}}; } @Override publicvoid failure(RetrofitError error) {
// Error handling}});Copy the code
There’s no performance problem, but you know it, I know it, you know it better if you’re working on a big project.
With RxJava, the code looks like this:
@GET("/token")
public Observable<String> getToken();
@GET("/user")
public Observable<User> getUser(@Query("token") String token, @Query("userId")
String userId);
getToken()
.flatMap(new Func1<String, Observable<User>>() {
@Override
public Observable<User> onNext(String token) {
return getUser(token, userId);
})
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling}});Copy the code
The logic is done with a flatMap(), which is still a chain. It just looks good, doesn’t it?
2. RxBinding
Rxjava-based Binding is an open source library from Jake Wharton that provides an RXJava-based Binding for the Android platform
API. Binding is the registration of Binding objects such as OnClickListener and TextWatcher
API.
Take an example of setting up click-listening. With RxBinding, event listeners can be set like this:
Button button = ... ; RxView.clickEvents(button)Observable returns click events as an Observable
.subscribe(new Action1<ViewClickEvent>() {
@Override
public void call(ViewClickEvent event) {
// Click handling}});Copy the code
It doesn’t seem to make much difference except in form, and it does in substance. Even if you look at the source code, you’ll see that it doesn’t even implement it
No surprises: inside it is implemented directly with a wrapped setOnClickListener(). However, this is just one
This change in form is exactly what RxBinding is all about: extensibility. Convert click listeners to RxBinding
After Observable, it’s possible to extend it. There are many ways to extend, depending on your needs. One example is the front
The aforementioned throttleFirst(), used to eliminate jitter, that is, the rapid chain of clicks caused by hand shaking:
RxView.clickEvents(button)
.throttleFirst(500, TimeUnit.MILLISECONDS)
.subscribe(clickAction);
Copy the code
3. Various asynchronous operations
The previous examples of Retrofit and RxBinding are two libraries that provide ready-made Observables. And if you have someone
Some asynchronous operations cannot automatically generate observables using these libraries and can write them themselves. For example, database read and write, large picture
All kinds of time-consuming operations that need to be done in the background, such as loading, file compression/decompression, can be done in RxJava, as described in previous chapters
Examples. I don’t think I need to do any more examples here.
4. RxBus
RxBus’s name looks like a library, but it’s not a library, it’s a pattern, and the idea is to implement it using RxJava
EventBus, which eliminates the need to use Otto or GreenRobot EventBus. By the way, Flipboard has replaced Otto with RxBus with no adverse reaction so far.
The last
RxJava is a difficult library for Android developers to get used to because it is so unfamiliar to Android developers
The concept of. But it’s really cool. That’s why I wrote RxJava For Android Developers to get started
Some beginner’s notes for people who don’t know what RxJava is, or for people who are using RxJava but still have doubts
A little bit more in-depth analysis. Anyway, as long as I can give you fellow Android engineers some help, what’s the purpose of this article
That’s it.