zoukankan      html  css  js  c++  java
  • 我们为什么要在Android中使用RxJava

    本文翻译来自–>Why should we use RxJava on Android
    另外: 微凉一季
    再另外: 微凉一季

    感觉RxJava近期风生水起,不学习一下都不好意思了。洒家也是初学RxJava,也是感觉代码好像更复杂更难懂了。看了一篇外文感同身受,简单翻译一下。本文简介使用RxJava优势所在。但可能须要有一点RxJava基础,推荐先看一下抛物线的那篇经典的匠心写作。
    —–华丽切割线。译文開始———

    Reactive Extensions (Rx) 是一系列接口和方法。为开发人员提供了一种易懂且迅速简单易维护的方法。

    RxJava就是干这事儿的,提供一系列tools来帮你写出简洁的代码。
    老实说,一開始我觉得RxJava 写的代码理解起来非常困难。而且引入一个库,单单就是为了用用这样的新式的api,这困扰到了我。后来。我懂了。以传统的编码方式。随着app的发展,我须要重构代码、一遍一遍的反复样板代码。以满足用户不断变更的新需求,这让我苦不堪言。
    我做的大量工作,事实上是改写相关方法和接口,就是由于需求的变更(这是开发与产品间那些血案的原罪)或者须要改变展示的信息亦或是须要改变处理信息数据..这非常抓狂。

    另外。这样的代码让其它来维护的人来理解,一般是非常耗时的。


    举个栗子:我们须要从数据库获取一组用户的链表数据,并展示出来。我们能够用AsyncTask后台查询数据库,获得的结果给Ui的适配器展示出来。简单演示样例代码:

    public class SampleTask extends AsyncTask<Void,Void,List<Users>> {
        private final SampleAdapter mAdapter;
    
        public SampleTask(SampleAdapter sampleAdapter) {
            mAdapter = sampleAdapater;
        }
    
        @Override
        protected List<Users> doInBackground(Void... voids) {
            //fetch there results from the database and return them to the onPostExecute
            List<Users> users = getUsersFromDatabase();
            return users;
        }
    
        @Override
        protected void onPostExecute(List<Users> users) {
            super.onPostExecute(products);
            // Checking if there are users on the database
            if(users == null) {
                //No users, presenting a view saying there are no users
                showEmptyUsersMessageView();
                return;
            }
            for(User user : users){
                mAdapter.add(user);
            }
            mAdapter.notifyDataSetChanged();
        }
    }

    如今有个新需求,要求仅仅显示非guest的user,我们处理的方法是,在加入到adapter前加个条件推断是不是guset,或者改变数据库查询的条件。

    更有甚者。你又被要求从数据库中获取另外的其它信息。跟user一并在这个adapter中显示出来呢?
    这就是我们为什么要用RxJava了,把我们从这个泥潭中拉出来。换个姿势。我们Rx代码是这样子(如果您已学习过Rx基础使用方法):

    public Observable<List<User>> fetchUsersFromDatabase() {
        return Observable.create(new Observable.OnSubscribe<List<User>(){
            @Override
            public void call(Subscriber<?

    super List<User>> subscriber){ // Fetch information from database subscriber.onNext(getUserList()); subscriber.onCompleted(); } }); }

    像这样被调用:

    fetchUsersFromDatabase()
    .subscribeOn(Schedulers.io())
    //will process everything in a new thread
    .observeOn(AndroidSchedulers.mainThread())
    //will listen the results on the main thread
    .subscribe(new Subscriber<List<User>>() {
               @Override
                public void onCompleted() {
                }
                @Override
                public void onError(Throwable e) {
                }
                @Override
                public void onNext(List<User> users) {
                    //Do whatever you want with each user
                }
            });

    開始改需求了哈
    怎么不显示guests呢。RxJava分分钟过滤掉这样的不速之客:

    fetchUsersFromDatabase()
            .filter(new Func1<User, Boolean>() {
                @Override
                public Boolean call(User user) {
                    //only return the users which are not guests
                    return !user.isGuest();
                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Subscriber<User>() {
                           @Override
                           public void onCompleted() {
                           }
    
                           @Override
                           public void onError(Throwable e) {
                               /*Check if there was any error while retrieving from database*/
                           }
    
                           @Override
                           public void onNext(User user) {
                               //Do whatever you want with each user
                           }
                       }
            );

    传统的方式,即便是个简单的变更。为了保持优雅的接口化编程,我们也得创建新接口,重构代码来实现过滤。

    可是使用RxJava让这一切变得优雅了,我们仅仅须要一个被观察者用来获取全部的信息,让后你就能够尽情的用这些方法来过滤获取你想要的数据。
    可能你又会说了。ok,这是非常好非常易读的结构。可是这似乎使代码量变多了呢。well you are right,可是这就是Retrolambda闪耀的时候了,这个库为我们兼容了以使用java8 lambda表达式,方法引用等等。


    帮我们简化代码例如以下:

    fetchUsersFromDatabase()
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(value -> {
                        //Do whatever with the value
                    },error -> {
                        //do something with in case of error
                    }
            );

    这个问题完美搞定,然后你又開始问了,我须要添加另外的查询结果和user一同显示在这个adapter中怎么破。这真不是事儿:

    fetchUsersFromDatabase()
            .zipWith(fetchSomethingElseFromDatabase(), (users, somethingElse) -> {
                /*here combine users and something else into a new object*/
            })
            .subscribe( o -> {
                /*use the combine object from users and something else to fill the adapter */
    });

    如上,我们能够轻松组合数据库查出来的其它数据和users给一个adapter一同显示。是不是更易维护。代码少。易读,清晰?
    如果要更深入的学习RXJava能够看以下这篇文章,我看后受益匪浅。


    [Party tricks with RxJava, RxAndroid & Retrolambda](https://medium.com/p/1b06ed7cd29c)
    另外,这篇教程 [tutorial ](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754) 也帮我在RxJava路上进阶了非常多。

  • 相关阅读:
    线程状态转换
    CyclicBarrier和CountDownLatch区别
    MySQL事务原理
    DownLoadManager[20530:228829] DiskImageCache: Could not resolve the absolute path of the old directory.
    App各种Icon及Launch image的尺寸和用途
    关于iPhone开发的一些建议
    iPhone6/6Plus下app状态栏内容放大问题处理
    PDF转jpg
    ios开发学习笔记
    nil和Nil和NULL的判断
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7400974.html
Copyright © 2011-2022 走看看