Maison Java javaDidacticiel 【Android】RxJava之初始篇

【Android】RxJava之初始篇

Nov 15, 2016 am 10:12 AM
rxjava

关于RxJava

RxJava是ReactiveX推出在Java VM环境下使用的异步操作库。除了在Java环境ReactiveX也为其他编程语言推出Rx库,例如Py、Js、Go等。网上有很多关于对RxJava的介绍和使用,在Android开发中也有很多项目使用RxJava。那为什么还要使用RxJava呢,Android开发也有提供异步操作的方法供开发者使用,我想应该是RxJava比起Handle、AsyncTask简洁优雅。

1 RxJava采用链式调用,在程序逻辑上清晰简洁

2 采用扩展式观察者设计模式

关于观察者模式以及其他RxJava的介绍这个就不做重复,下面内容主要围绕RxJava和RxAndroid使用。对于RxJava官方文档已经有详细介绍,本节是以学习讨论为主,如存在错误的地方希望大家可以指出。

被观察者Observable

使用RxJava需要创建Observable,Observable用于发射数据。如下Observable的create方法需要传入一个OnSubscribe,其继承于Action1>,Action中的Subscriber就是订阅者。

public static <T> Observable<T> create(OnSubscribe<T> f) { 
    return new Observable<T>(RxJavaHooks.onCreate(f)); 
}
Copier après la connexion

另外create方法中需要实现接口call,返回subscriber对象。call方法实现在observable订阅后要执行的事件流。subscriber.onNext发射data,subscriber.onCompleted可以表示发射事件结束。接着调用observable的subscribe方法实现被订阅后执行的事件流。

Observable<String> observable = Observable 
                .create(new Observable.OnSubscribe<String>() { 
 
            @Override 
            public void call(Subscriber<? super String> subscriber) { 
                subscriber.onNext("1"); 
                subscriber.onNext("2"); 
                subscriber.onNext("3"); 
                subscriber.onNext("4"); 
                subscriber.onNext("5"); 
            } 
}); 
Subscriber<String> subscriber = new  Subscriber<String>() { 
            @Override 
            public void onCompleted() { 
 
            } 
 
            @Override 
            public void onError(Throwable e) { 
 
            } 
 
            @Override 
            public void onNext(String s) { 
                System.out.print(s + &#39;\n&#39;); 
            } 
}; 
observable.subscribe(subscriber); 
//输出结果 print: 
//1 
//2 
//3 
//4 
//5
Copier après la connexion

Observable除了使用create方法创建外还可以使用from或者just快速设置发射的事件流,简化了create的步骤。

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

Observable<String> o = Observable.from("a", "b", "c");
Copier après la connexion

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

Observable<String> o = Observable.just("one object");
Copier après la connexion

说好的异步操作

RxJava的线程由Schedulers调度者控制,通过它来控制具体操作在什么线程中进行。

Schedulers.immediate() 在当前线程中执行

Schedulers.newThread() 为每一个任务开辟线程执行

Schedulers.computation() 计算任务运行的线程

Schedulers.io() IO任务运行的线程....

AndroidSchedulers.mainThread() Android 主线程运行

对于线程的控制主要由subscribeOn()和observeOn()两个方法控制:

subscribeOn 控制Observable.OnSubscribe所处的线程,等同于Observable create、just、from时所处的线程。

observeOn 控制Subscriber的线程,也可以说是控制事件被执行时所在的线程。

Observable 
        .just(1,2,3) 
        .subscribeOn(Schedulers.io()) 
        .observeOn(AndroidSchedulers.mainThread()) 
        .subscribe(new Subscriber<Integer>() { 
            @Override 
            public void onCompleted() { 
 
            } 
 
            @Override 
            public void onError(Throwable e) { 
 
            } 
 
            @Override 
            public void onNext(Integer integer) { 
                 System.out.print(integer + &#39;\n&#39;);                        
            } 
}); 
//输出结果 print: 
//1 
//2 
//3
Copier après la connexion

写下上面的RxJava链式调用的代码,有没有觉得比以前使用的异步调用清爽许多,对处女座还说这很治愈!

操作符Operators

ReactiveX提供超级多的操作符,每个操作符都具有不同的功能,但目的都是在Observable和Subscribe之间变换和修改发射出去的事件流。这节介绍几个比较常见简单的操作符,之后有机会再写一节操作符篇详细说说每个操作符的作用。附上官方操作符文档看看就知道有多少多了。

Map()

public final <R> Observable<R> map(Func1<? super T, ? extends R> func) { 
        return create(new OnSubscribeMap<T, R>(this, func)); 
    }
Copier après la connexion

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

首先先介绍一个操作符map,map实现Func1接口将T类型数据变换为R类型数据,返回R类型数据。例如传入Integer类型的事件队列,经过map加工之后以String类型返回。

Observable 
                .just(1,2,3) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                    ...... 
                    @Override 
                    public void onNext(String str) { 
                        System.out.print(str + &#39;\n&#39;); 
                    } 
                }); 
//输出结果 print: 
//1 
//2 
//3
Copier après la connexion

Filter()

public final Observable<T> filter(Func1<? super T, Boolean> predicate) { 
       return create(new OnSubscribeFilter<T>(this, predicate)); 
   }
Copier après la connexion

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

filter和map一样实现Func1接口不过它变换之后的类型为boolean,对发射的事件流进行筛选,当变换后的boolean值为true,订阅者才能收到通过筛选的事件,反之该事件不被消费。例如事件流筛选要求当int值可被2整除才能继续传递,所以最后订阅者可消费的事件为2,4,6,8,10。

Observable 
                .just(1,2,3,4,5,6,7,8,9,10) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .filter(new Func1<Integer, Boolean>() { 
                    @Override 
                    public Boolean call(Integer integer) { 
                        return integer % 2 == 0; 
                    } 
                }) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                   ...... 
                    @Override 
                    public void onNext(String str) { 
                        System.out.print(str + &#39;\n&#39;); 
                        Log.i("subscribe", str); 
                    } 
                }); 
//输出结果 print: 
//2 
//3 
//4 
//6 
//8 
//10
Copier après la connexion

Skip()

public final Observable<T> skip(int count) { 
        return lift(new OperatorSkip<T>(count)); 
    }
Copier après la connexion

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

skip操作符表示跳过前几个事件从某一个事件开始发射事件,下标从0开始。

Observable 
                .just(1,2,3,4,5,6,7,8,9,10) 
                .subscribeOn(Schedulers.io()) 
                .observeOn(AndroidSchedulers.mainThread()) 
                .skip(3) 
                .map(new Func1<Integer, String>() { 
                    @Override 
                    public String call(Integer integer) { 
                        return integer + ""; 
                    } 
                }) 
                .subscribe(new Subscriber<String>() { 
                    ...... 
                    @Override 
                    public void onNext(String s) { 
                        System.out.print(s + &#39;\n&#39;); 
                        Log.i("subscribe", s); 
                    } 
                }); 
//输出结果 print: 
//4 
//5 
//6 
//7 
//8 
//9 
//10
Copier après la connexion

Range()

public static Observable<Integer> range(int start, int count) { 
        if (count < 0) { 
            throw new IllegalArgumentException("Count can not be negative"); 
        } 
        if (count == 0) { 
            return Observable.empty(); 
        } 
        if (start > Integer.MAX_VALUE - count + 1) { 
            throw new IllegalArgumentException("start + count can not exceed Integer.MAX_VALUE"); 
        } 
        if(count == 1) { 
            return Observable.just(start); 
        } 
        return Observable.create(new OnSubscribeRange(start, start + (count - 1))); 
    }
Copier après la connexion

wKioL1gpuyiQg_r1AAAg8NiIJgI696.png

range操作符可以理解为just,from传递一个连续的int类型待发射数组,n为起始int值,m为Count。例如n = 1,m = 5 int数组就是{1,2,3,4,5}

结尾

这节先学习到这,算是对RxJava的初步认识和学习。其实运用RxJava主要还是依赖于对操作符的使用,前面所介绍的操作符属于最最简单基础的,还有很多特别有用的操作符没有介绍。之后再继续介绍一些操作符。RxJava在Android开发中很受欢迎,就是因为它的强大,同时RxJava可以和Retrofit组合使用,更高效处理网络请求回值。另外GitHub GoogleSample上的android-architecture也有使用RxJava框架的TODO项目,可以看看理解RxJava在项目中的实践应用。


Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le logiciel de sécurité de l'entreprise entraîne-t-il l'exécution de l'application? Comment dépanner et le résoudre? Le logiciel de sécurité de l'entreprise entraîne-t-il l'exécution de l'application? Comment dépanner et le résoudre? Apr 19, 2025 pm 04:51 PM

Dépannage et solutions au logiciel de sécurité de l'entreprise qui fait que certaines applications ne fonctionnent pas correctement. De nombreuses entreprises déploieront des logiciels de sécurité afin d'assurer la sécurité des réseaux internes. ...

Comment simplifier les problèmes de cartographie des champs dans l'amarrage du système à l'aide de mapstruct? Comment simplifier les problèmes de cartographie des champs dans l'amarrage du système à l'aide de mapstruct? Apr 19, 2025 pm 06:21 PM

Le traitement de la cartographie des champs dans l'amarrage du système rencontre souvent un problème difficile lors de l'exécution d'amarrage du système: comment cartographier efficacement les champs d'interface du système a ...

Comment obtenir élégamment des noms de variables de classe d'entité pour créer des conditions de requête de base de données? Comment obtenir élégamment des noms de variables de classe d'entité pour créer des conditions de requête de base de données? Apr 19, 2025 pm 11:42 PM

Lorsque vous utilisez MyBatis-Plus ou d'autres cadres ORM pour les opérations de base de données, il est souvent nécessaire de construire des conditions de requête en fonction du nom d'attribut de la classe d'entité. Si vous manuellement à chaque fois ...

Comment Intellij Idea identifie-t-elle le numéro de port d'un projet de démarrage de printemps sans publier un journal? Comment Intellij Idea identifie-t-elle le numéro de port d'un projet de démarrage de printemps sans publier un journal? Apr 19, 2025 pm 11:45 PM

Commencez le printemps à l'aide de la version IntelliJideaultimate ...

Comment convertir les noms en nombres pour implémenter le tri et maintenir la cohérence en groupes? Comment convertir les noms en nombres pour implémenter le tri et maintenir la cohérence en groupes? Apr 19, 2025 pm 11:30 PM

Solutions pour convertir les noms en nombres pour implémenter le tri dans de nombreux scénarios d'applications, les utilisateurs peuvent avoir besoin de trier en groupe, en particulier en un ...

Comment convertir en toute sécurité les objets Java en tableaux? Comment convertir en toute sécurité les objets Java en tableaux? Apr 19, 2025 pm 11:33 PM

Conversion des objets et des tableaux Java: Discussion approfondie des risques et des méthodes correctes de la conversion de type de distribution De nombreux débutants Java rencontreront la conversion d'un objet en un tableau ...

Plateforme de commerce électronique SKU et conception de la base de données SPU: comment prendre en compte à la fois les attributs définis par l'utilisateur et les produits sans attribution? Plateforme de commerce électronique SKU et conception de la base de données SPU: comment prendre en compte à la fois les attributs définis par l'utilisateur et les produits sans attribution? Apr 19, 2025 pm 11:27 PM

Explication détaillée de la conception des tables SKU et SPU sur les plates-formes de commerce électronique Cet article discutera des problèmes de conception de la base de données de SKU et SPU dans les plateformes de commerce électronique, en particulier comment gérer les ventes définies par l'utilisateur ...

Comment obtenir élégamment les conditions de requête de création de nom de variable de classe d'entité lors de l'utilisation de tkmybatis pour la requête de base de données? Comment obtenir élégamment les conditions de requête de création de nom de variable de classe d'entité lors de l'utilisation de tkmybatis pour la requête de base de données? Apr 19, 2025 pm 09:51 PM

Lorsque vous utilisez TkMyBatis pour les requêtes de base de données, comment obtenir gracieusement les noms de variables de classe d'entité pour créer des conditions de requête est un problème courant. Cet article épinglera ...

See all articles