NotRxJava懒人指南外文翻译资料
2023-03-02 15:11:20
NotRxJava guide for lazy folks
These days if you are an android developer, you might hear some hype about RxJava. RxJava is library which can help you get rid of all you complex write-only code that deals with asynchronous events. Once you start using it in your project – you will use it everywhere.
The main pitfall here is steep learning curve. If you have never used RxJava before, it will be hard or confusing to take full advantage of it for the first time. The whole way you think about writing code is a little different. Such learning curve creates problems for massive RxJava adoption in most projects.
Of course there are a lot of tutorials and code examples around that explain how to use RxJava. Developer interested in learning and using RxJava can first visit the official Wiki that contains great explanation of what Observable is, how itrsquo;s related to Iterable and Future. Another useful resource is How To Use RxJava page which shows code examples of how to emit items and println them.
But what one really wants to know, is what problem RxJava will solve and how it will help organize async code without actually learning what Observable is.
My goal here is to show some “prequel” to read before the official documentation in order to better understand the problems that RxJava tries to solve. This article is positioned as a small walk-through on how to reorganize messy Async code by ourselfs to see how we can implement basic principles of RxJava without actually using RxJava.
So If you are still curious letrsquo;s get started!
Cat App
So letrsquo;s create a real world example. So we know that cats are the engine of technology progress, so letrsquo;s build a typical app for downloading cat pictures.
So here is the task:
We have a webservice that provides api to search the whole internet for images of cats by given query. Every image will contain cuteness parameter - integer value that describes how cute is that picture. Our task will be download a list of cats, choose the most cutest, and save it to local storage.
We will focus only on downloading, processing and saving cats data.
So letrsquo;s start:
Model and API
Here is a simple data structure that will describe our lsquo;Catrsquo;
public class Cat implements Comparablelt;Catgt;{
Bitmap image;
int cuteness;
@Override
public int compareTo(Cat another) {
return Integer.compare(cuteness, another.cuteness);
}
}
And our api calls that we will use from cat-sdk.jar will be in good-old blocking style.
public interface Api {
Listlt;Catgt; queryCats(String query);
Uri store(Cat cat);
}
Heh, seems clear yet? Sure! Letrsquo;s write client business logic.
public class CatsHelper {
Api api;
public Uri saveTheCutestCat(String query){
Listlt;Catgt; cats = api.queryCats(query);
Cat cutest = findCutest(cats);
Uri savedUri = api.store(cutest);
return savedUri;
}
private Cat findCutest(Listlt;Catgt; cats) {
return Collections.max(cats);
}
}
Damn, so clear and so simple. Letrsquo;s think a bit about how cool this code is. The main method saveTheCutestCat contains only 3 functions. Take a few minutes to look at code and think about functions. This fundamental feature of our language is so amazing. You take functions, feed the input, and receive the output of it. And we wait while function is doing its work.
So simple and yet so powerful. Letrsquo;s think about another advantages of simple functions:
Composition
As you can see we created one function (saveTheCutestCat) from 3 others, thus we composed them. Any of those functions is like LEGO blocks: we use them to connect one to another to get composed LEGO block (which actually can be composed later). Composing functions is so simple – just feed result of one function as argument to another in right order, what could be simpler?
Error propagation
Another good thing about functions is the way we deal with errors. Any function can terminate its execution with error, in java we call it throwing an Exception. And this error can be handled on any level. In java we do this with try/catch block. The key point here is that we donrsquo;t need to handle errors for every function, but we can handle all possible errors for the whole block of code. Like:
try{
Listlt;Catgt; cats = api.queryCats(query);
Cat cutest = findCutest(cats);
Uri savedUri = api.store(cutest);
return savedUri;
} catch (Exception e) {
e.printStackTrace()
return someDefaultValue;
}
In this case we will handle any errors that happen during the execution. Or we can propagate it to the next level, if we just leave our code without try/catch block.
Go Async
But we live in a world where we cannot wait. Sometimes itrsquo;s not possible to have only blocking calls. And actually in android you always need to deal with asynchronous code.
Take for example Androidrsquo;s default OnClickListener. When you want to handle a view click, you must provide a listener (callback) which will be invoked when user clicks. And there is no reasonable way to receive clicks in a blocking manner. So clicks are always asynchronous. So letrsquo;s try to deal with async code now.
Async network call
Letrsquo;s now imagine that to make a query we use some non-blocking HTTP client (like Ion). So imagine ourcats-sdk.jar has updated and replaced itrsquo;s API with async calls.
So new Api interface:
public interface Api {
interface CatsQueryCallback {
void onCatListReceived(Listlt;Catgt; cats);
void onError(Exception e);
}
void queryCats(String query, CatsQueryCallback catsQueryCallback);
U
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[499562],资料为PDF文档或Word文档,PDF文档可免费转换为Word