zoukankan      html  css  js  c++  java
  • 深入浅出RxJava

    深入浅出RxJava(一:基础篇)

    深入浅出RxJava(二:操作符)

    深入浅出RxJava三--响应式的好处

    深入浅出RxJava四-在Android中使用响应式编程

    RxJava 到底是什么?

    一个词:异步

    RxJava 好在哪?

    换句话说,『同样是做异步,为什么人们用它,而不用现成的 AsyncTask / Handler / XXX / ... ?』

    一个词:简洁

    RxJava 的优势也是简洁,但它的简洁的与众不同之处在于,随着程序逻辑变得越来越复杂,它依然能够保持简洁。

     

     (一)基本使用

    1, 创建一个Observable对象,直接调用Observable.create即可
    [java] view plain copy
     
    1. Observable<String> myObservable = Observable.create(  
    2.     new Observable.OnSubscribe<String>() {  
    3.         @Override  
    4.         public void call(Subscriber<? super String> sub) {  
    5.             sub.onNext("Hello, world!");  
    6.             sub.onCompleted();  
    7.         }  
    8.     }  
    9. );  
    这里定义的Observable对象仅仅发出一个Hello World字符串,然后就结束了。

     2, 创建一个Subscriber来处理Observable对象发出的字符串。

    [java] view plain copy
     
    1. Subscriber<String> mySubscriber = new Subscriber<String>() {  
    2.     @Override  
    3.     public void onNext(String s) { System.out.println(s); }  
    4.   
    5.     @Override  
    6.     public void onCompleted() { }  
    7.   
    8.     @Override  
    9.     public void onError(Throwable e) { }  
    10. };  

     这里subscriber仅仅就是打印observable发出的字符串。

    3, 通过subscribe函数就可以将我们定义的myObservable对象和mySubscriber对象关联起来,这样就完成了subscriber对observable的订阅。

    myObservable.subscribe(mySubscriber);  
    一旦mySubscriber订阅了myObservable,myObservable就会调用mySubscriber对象的onNext和onComplete方法,mySubscriber就会打印出Hello World!
     

    (二)操作符

    map: 映射, 变换, 用来把把一个事件转换为另一个事件的。

    flatMap: 平滑映射, 接收一个Observable的输出作为输入,同时输出另外一个Observable。

    filter: 过滤, 输出和输入相同的元素,并且会过滤掉那些不满足检查条件的。

    doOnNext(): 在每次输出一个元素之前做一些额外的事情

    take: 输出最多指定数量的结果。

    ...更多操作符请查看官方api文档.

     

     (三)响应式的好处

    (四)在Android中使用响应式编程

    例子:

    假设有这样一个需求:界面上有一个自定义的视图 imageCollectorView ,它的作用是显示多张图片,并能使用 addImage(Bitmap) 方法来任意增加显示的图片。现在需要程序将一个给出的目录数组 File[] folders 中每个目录下的 png 图片都加载出来并显示在imageCollectorView 中。需要注意的是,由于读取图片的这一过程较为耗时,需要放在后台执行,而图片的显示则必须在 UI 线程执行。常用的实现方式有多种,我这里贴出其中一种:

    new Thread() {
        @Override
        public void run() {
            super.run();
            for (File folder : folders) {
                File[] files = folder.listFiles();
                for (File file : files) {
                    if (file.getName().endsWith(".png")) {
                        final Bitmap bitmap = getBitmapFromFile(file);
                        getActivity().runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                imageCollectorView.addImage(bitmap);
                            }
                        });
                    }
                }
            }
        }
    }.start();

    而如果使用 RxJava ,实现方式是这样的:

    Observable.from(folders)
        .flatMap(new Func1<File, Observable<File>>() {
            @Override
            public Observable<File> call(File file) {
                return Observable.from(file.listFiles());
            }
        })
        .filter(new Func1<File, Boolean>() {
            @Override
            public Boolean call(File file) {
                return file.getName().endsWith(".png");
            }
        })
        .map(new Func1<File, Bitmap>() {
            @Override
            public Bitmap call(File file) {
                return getBitmapFromFile(file);
            }
        })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Bitmap>() {
            @Override
            public void call(Bitmap bitmap) {
                imageCollectorView.addImage(bitmap);
            }
        });

    那位说话了:『你这代码明明变多了啊!简洁个毛啊!』大兄弟你消消气,我说的是逻辑的简洁,不是单纯的代码量少(逻辑简洁才是提升读写代码速度的必杀技对不?)。观察一下你会发现, RxJava 的这个实现,是一条从上到下的链式调用,没有任何嵌套,这在逻辑的简洁性上是具有优势的。当需求变得复杂时,这种优势将更加明显(试想如果还要求只选取前 10 张图片,常规方式要怎么办?如果有更多这样那样的要求呢?再试想,在这一大堆需求实现完两个月之后需要改功能,当你翻回这里看到自己当初写下的那一片迷之缩进,你能保证自己将迅速看懂,而不是对着代码重新捋一遍思路?)。

    另外,如果你的 IDE 是 Android Studio ,其实每次打开某个 Java 文件的时候,你会看到被自动 Lambda 化的预览,这将让你更加清晰地看到程序逻辑:

    Observable.from(folders)
        .flatMap((Func1) (folder) -> { Observable.from(file.listFiles()) })
        .filter((Func1) (file) -> { file.getName().endsWith(".png") })
        .map((Func1) (file) -> { getBitmapFromFile(file) })
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe((Action1) (bitmap) -> { imageCollectorView.addImage(bitmap) }); 

    深入原理:给 Android 开发者的 RxJava 详解

  • 相关阅读:
    WORD窗体保护密码清除
    在Fedora 23 Server和Workstation上安装LAMP(Linux, Apache, MariaDB和PHP)
    firefox 提示 ssl_error_unsupported_version 的解决方法
    算法题:求一个序列S中所有包含T的子序列(distinct sub sequence)
    Django模板输出Dict所有Value的效率问题
    笔记:LNK2001不代表链接器真的需要链接相关符号
    Windows Restart Manager 重启管理器
    advapi32.dll kernel32.dll 中的两套注册表API
    使用GDI+保存带Alpha通道的图像(续)
    使用GDI+保存带Alpha通道的图像
  • 原文地址:https://www.cnblogs.com/wytiger/p/5941459.html
Copyright © 2011-2022 走看看