Coroutine Flow principle

What is Flow

Flow literally means "flow", which means that our tasks are divided and processed step by step like water flow. Imagine there is a task that requires you to get water from the mountains. What do you need to do?

  • Carrying a carrying pole and walking dozens of miles along mountain roads to carry water back. It's simple and crude, but it's possible that when you walk dozens of miles and find that the water has dried up, your trip has been in vain.
  • Set up a water pipe from your home to the water source, and then you can open the water pipe at home and have water to drink. If you turn on the faucet and there is no water, then you know that the sink is out of water, and you don't have to make a trip in vain.

This actually extends to the two current mainstream programming ideas, responsive and non-responsive.

The so-called responsiveness is to wait for the data source to deliver the data through subscription and monitoring. Its advantage is that it can be easily decoupled from the data source logic, and the data flow can be changed at will before the data source can be passed over. For example, in the above example, if I want to drink lemon-flavored water, then I can definitely connect a lemon-flavored pipe to my faucet. The traditional solution requires adding lemon essence to the water source. At this time, if another person wants to drink watermelon-flavored water, it will not be possible.

Why Flow

Before Flow, RXjava has always been our commonly used flow writing method. So what are the advantages of Flow compared to RXjava? ChatGpt believes in the following points:

  1. More lightweight: Flow is part of the Kotlin standard library and does not need to introduce additional dependent libraries, while RxJava needs to introduce the RxJava core library and related operator libraries, which increases the complexity and volume of the project.
  2. Simpler: Flow is implemented based on Kotlin coroutines. Using the syntactic sugar of coroutines can make the code simpler and easier to read, which is simpler than RxJava.
  3. More flexible: Flow supports back-pressure processing and multiple subscribers subscribing to the same data stream at the same time, while RxJava needs to use operators such as or share()for processing multiple subscribers .replay()
  4. More secure: Flow can run in the context of a coroutine, so it can avoid common thread safety issues and memory leaks in RxJava.
  5. More predictable: Flow uses Kotlin's type safety features to more easily avoid problems such as type mismatches and null pointer exceptions.

In fact, as a developer, what you care about most is simplicity. The simpler the usage means the lower the learning cost, and the less likely it is to make mistakes and cause unpredictable problems.

For more Android development study notes, please click here to get them for free

Intuitive comparison of traditional solutions, RXjava, and Flow

Let’s take the most commonly used example, sub-thread network request, and then return the data to the main thread to load the UI.

traditional solution
OkHttpUtils.sendGetRequest("http://example.com", new OkHttpUtils.CallbackListener() {
   
    
    
    @Override
    public void onSuccess(String response) {
   
    
    
        // 在主线程中处理请求成功的结果
        textView.setText(response);
    }
    @Override
    public void onFailure(IOException e) {
   
    
    
        // 在主线程中处理请求失败的结果
        e.printStackTrace();
        Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
    }
});

Initiate a network request and register a listener, and call back the result when the request result comes back. If we need to request the second interface back after the network request is successful at this time, then we need to nest another callback, like this:

OkHttpUtils.sendGetRequest("http://example.com", new OkHttpUtils.CallbackListener() {
   
    
    
    @Override
    public void onSuccess(String response) {
   
    
    
        // 在主线程中处理请求成功的结果
        OkHttpUtils.sendGetRequest("http://example2.com", new OkHttpUtils.CallbackListener() {
   
    
    
            @Override
            public void onSuccess(String response) {
   
    
    
                // 在主线程中处理请求成功的结果
                textView.setText(response);
            }
            @Override
            public void onFailure(IOException e) {
   
    
    
                // 在主线程中处理请求失败的结果
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
            }
        });
    }
    @Override
    public void onFailure(IOException e) {
   
    
    
        // 在主线程中处理请求失败的结果
        e.printStackTrace();
        Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();
    }
});

It can be seen that when there are two levels, we are completely trapped in "callback hell", and the logic becomes increasingly difficult to understand intuitively. What's even more fatal is that this method cannot be expanded. For example, another user wants to pop up a bubble after the first request is successful, and the second user says I don't need it. In this way, you can only add parameters and write if-else judgments. If things go on like this, this method will expand rapidly and can no longer be reused. Then the CV1.0 and 2.0 versions of this method will begin to "make their debut", and finally this class will no longer be maintained.

RXjava solution
RxJavaUtils.sendGetRequest("http://example.com")
        .subscribe(new Observer<String>() {
   
    
    
            @Override
            public void onSubscribe(Disposable d) {
   
    
    
                // 在这里可以做一些准备工作,比如显示进度条等
            }
            @Override
            public void onNext(String response) {
   
    
    
                // 在主线程中处理请求成功的结果
                textView.setText(response);
            }
            @Override
            public void onError(Throwable e) {
   
    
    
                // 在主线程中处理请求失败的结果
                e.printStackTrace();
                Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT
           })

Guess you like

Origin blog.csdn.net/m0_70748458/article/details/130626056