美文网首页
Android RxJava + lambda 的使用

Android RxJava + lambda 的使用

作者: 々志尚 | 来源:发表于2017-12-27 18:35 被阅读0次

    使用RxJava、RxAndroid 、Lambda 也有一段时间了,这时我的第一篇发布的文章,希望对初学的程序员们有所帮助啦

    (本片只讲用法,不说原理需要学习原理的话可以到 http://gank.io/post/560e15be2dca930e00da1083)

    本人使用的 rx1 ,IDE工具 Android Studio 2.3 + JDK 1.8

    1.首先需要在我们的 app的目录下面 build.gradle 配置 

    android{

    defaultConfig{

    // Lambda & Stream

    jackOptions {

    enabled true

    }

    }

    compileOptions {

    sourceCompatibility JavaVersion.VERSION_1_8

        targetCompatibility JavaVersion.VERSION_1_8

    }

    }

    dependencies{

    // 1.RxJava RxAndroid

    compile'io.reactivex:rxjava:1.1.0'

    compile'io.reactivex:rxandroid:1.1.0'

    compile'com.f2prateek.rx.preferences:rx-preferences:1.0.1'

    compile'com.jakewharton.rxbinding:rxbinding:0.4.0'

    compile'com.trello:rxlifecycle:0.4.0'

    compile'com.trello:rxlifecycle-components:0.4.0'

    // 2Lambda & Stream

    compile'com.annimon:stream:1.1.5'

    }

    2.在项目的build.greadle 下 加入

    classpath'me.tatarka:gradle-retrolambda:3.5.0' // Add By Howe - Lambda

    如:

    dependencies {

    classpath'com.android.tools.build:gradle:2.3.0'

        classpath'me.tatarka:gradle-retrolambda:3.5.0' // Add By Howe - Lambda

    }

    好啦,android 和 Lambda 的属性就此配置完成啦

    看一下效果图

    这里详细介绍了如何运用 RxJava 创建数据,使用数据,筛选数据,替换数据

    调用数据的三大常用方法:create、from、just

    数据筛选的常用方法:map、flatMap、filter、lift、compose

    1)创建方法:Observable.create

    Observable.create(new Observable.OnSubscribe() {

    @Override

                public void call(Subscriber subscriber) {

                               subscriber.onNext("Hello");

                               subscriber.onNext("Hi");

                               subscriber.onNext("Aloha");

                               subscriber.onCompleted();

                }

    })

    .subscribeOn(Schedulers.io())

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(new Observer() {

    Stringtext ="";

        @Override

        public void onCompleted() {

        }

    @Override

        public void onError(Throwable e) {

    }

    @Override

        public void onNext(String s) {

        }

    });

    很简单的一个创建方法,

    可以看到,这里传入了一个 OnSubscribe 对象作为参数。OnSubscribe 会被存储在返回的 Observable 对象中,它的作用相当于一个计划表,当 Observable 被订阅的时候,OnSubscribe 的 call() 方法会自动被调用,事件序列就会依照设定依次触发(对于上面的代码,就是观察者Subscriber 将会被调用三次 onNext() 和一次 onCompleted())。这样,由被观察者调用了观察者的回调方法,就实现了由被观察者向观察者的事件传递,即观察者模式。

    2) 方法 from

    String[]words = {"Hello", "Hi", "Aloha", "", null, "最后"};

    // from : 数据可以切换,不一定说传什么就返回什么

    Observable.from(words)

    // 判断是否存在

    // .exists(i -> StringUtils.isNotEmpty(i))

    // 判断是否存在

    // .map((Func1) s -> StringUtils.isNotEmpty(s));

                .map(new Func1() {

    @Override

            public Integer call(String s) {

    return StringUtils.isNotEmpty(s) ?0 :1;

            }

    })

    // lambda 表达式

    //.lift((Observable.Operator) subscriber -> new Subscriber() {

    // 替换/转换对象

                .lift(new Observable.Operator() {

    @Override

            public Subscriber call(Subscriber subscriber) {

    return new Subscriber() {

                     @Override

                    public void onCompleted() { }

                     @Override

                    public void onError(Throwable e) { }

                   @Override

                    public void onNext(Integer integer) {

    subscriber.onNext("" + integer);

                    }

    };

            }

    })

    .subscribe(new Action1() {

    String text ="";

            @Override

            public void call(String s) {

    text += s;

                mText.setText(text);

            }

    });

    效果图如下:

    3)方法 just

    int[] data1 = {11,12,13,14,15,16,17,18,19};

    int[] data2 = {21,22,23,24,25,26,27,28,29};

    int[] data3 = {31,32,33,34,35,36,37,38,39};

    // just: 传什么返回什么,需要用 替换/转换的方法转类型

    Observable.just(data1, data2, data3)

    .filter(new Func1() {

    @Override

        public Boolean call(int[] ints) {

    return ints.length >0;

    }

    })

    .flatMap(new Func1>() {

    @Override

        public Observable call(int[] ints) {

    // 不能在用just:否则我不能拆分数组

            return Observable.from(getStringCom(ints));// 转成 String[] 类型

        }

    })

    // 可要可无

            .lift(new Observable.Operator() {

    @Override

        public Subscriber call(Subscriber subscriber) {

    return new Subscriber() {

    @Override

                public void onCompleted() { }

    @Override

                public void onError(Throwable e) { }

    @Override

                public void onNext(String s) {

    subscriber.onNext(s);

    }

    };

    }

    })

    // 上加了线程切换会和上面的lift的观察者发生交集错误

    // .subscribeOn(Schedulers.io())

    // .observeOn(AndroidSchedulers.mainThread())

            .subscribe(new Action1() {

    Stringtext ="";

    @Override

        public void call(String str) {

    text +="\n" + str;

    mText.setText(text);

    }

    });

    输出结果(都是换行的):11,12,13,14,15,16,17,18,19,21,22,23,24,25,26,27,28,29,31,32,33,34,35,36,37,38,39

    // lambda 表达式写法

    Observable.just(data1, data2, data3)

    .filter(i -> i.length >0)

    .flatMap(ints -> Observable.from(getStringCom(ints)))

    .lift((Observable.Operator) subscriber ->new Subscriber() {

    @Override

        public void onCompleted() { }

    @Override

        public void onError(Throwable e) { }

    @Override

        public void onNext(String s) {

    subscriber.onNext(s);

    }

    })

    // 上加了线程切换会和上面的lift的观察者发生交集错误

    // .subscribeOn(Schedulers.io())

    // .observeOn(AndroidSchedulers.mainThread())

            .subscribe(s -> mText.setText(s));

    效果图:使用 just 方法创建 被观察者,如果没有替换数据的话,你传什么就返回什么的,代码里面的注释已经说的很清楚啦


    4)Map 和 flatMap 

    原理:http://blog.csdn.net/new_abc/article/details/48025513

    Drawable[] b = {getResources().getDrawable(R.mipmap.icon1), getResources().getDrawable(R.mipmap.icon1)};

    Observable.from(b)

    // 筛选 方法 从上往下 执行

            .flatMap(new Func1>() {

    @Override

                public Observablecall(Drawable bitmap) {

    // Toast.makeText(TwoRxJavaActivity.this, "哈哈哈哈哈", Toast.LENGTH_SHORT).show(); // 添加了这句话.subscribeOn(Schedulers.io())已经是主线程之外的方法了

                    return Observable.from(new Drawable[]{bitmap});

                }

    })

    .filter(i -> i !=null)

    .map(new Func1() {

    @Override

                public Bitmapcall(Drawable drawable) {

    BitmapDrawable bd = (BitmapDrawable) drawable;

                    Bitmap bm = bd.getBitmap();

                    return bm;

                }

    })

    // 把加载图片的处理放在主线程之外,可以防止短时间的卡顿,让用户使用app更加的随心应手

            .subscribeOn(Schedulers.io())// 指定 subscribe() 发生在 IO 线程:所以 flatMap、filter、map都会发生在主线程之外,不能更新界面信息

            .observeOn(AndroidSchedulers.mainThread())// // 指定 Subscriber 的回调发生在主线程:所以 new 出来的 观察则 都会发生在主线程中

            .subscribe(new Action1() {

    @Override

                public void call(Bitmap bitmap) {

    Toast.makeText(TwoRxJavaActivity.this, "哈哈哈哈哈", Toast.LENGTH_SHORT).show();

                    mImg.setImageBitmap(bitmap);

                }

    });

    效果图:

    Map 和 flatMap 都有替换的功能,不过Map 只是一对一关系,而 flatMap 有一对多,所以相对更强大好用

    5)方法 filter

    主要作用就是判断,返回值是 Boolean 

    int[] data = {1,2,3,4,5,6,7,8,9,0};

    // filter 返回 true/false

    Observable.just(data)

    // 判断 数组 data 的长度大于0

            .filter(i -> i.length >0)

    // .flatMap((Func1>) ints -> Observable.from(getStringCom(ints))) // lambda 表达式

    // 转换成 String[] 类型,然后用from 一个一个的读取出来

            .flatMap(new Func1>() {

    @Override

        public Observable call(int[] ints) {

    return Observable.from(getStringCom(ints));

    }

    })

    // 判断 是否是偶数取值

            .filter(i -> Integer.valueOf(i) %2 ==0)

    .subscribe(new Action1() {

    Stringtext ="";

    @Override

        public void call(String s) {

    text +="\n" + s;

    mText.setText(text);

    }

    });

    结果:2,4,6,8,0

    效果图:

    6)方法 lift

    String[]words = {"Hello", "Hi", "Aloha", "", null, "最后"};

    // from : 数据可以切换,不一定说传什么就返回什么

    Observable.from(words)

    // 判断是否存在

    // .exists(i -> StringUtils.isNotEmpty(i))

    // 判断是否存在

    // .map((Func1) s -> StringUtils.isNotEmpty(s));

    .map(new Func1() {

    @Override

            public Integer call(String s) {

    return StringUtils.isNotEmpty(s) ?0 :1;

            }

    })

    // lambda 表达式

    //.lift((Observable.Operator) subscriber -> new Subscriber() {

    // 替换/转换对象

    .lift(new Observable.Operator() {

    @Override

    public Subscriber call(Subscriber subscriber) {

    return new Subscriber() {

                     @Override

                    public void onCompleted() { }

     @Override

                    public void onError(Throwable e) { }

                   @Override

                    public void onNext(Integer integer) {

    subscriber.onNext("" + integer);

                    }

    };

            }

    })

    .subscribe(new Action1() {

    String text ="";

            @Override

            public void call(String s) {

    text += s;

                mText.setText(text);

            }

    });

    效果图如下:

    7)方法 compose

    compose: 对 Observable 整体的变换

    除了 lift() 之外, Observable 还有一个变换方法叫做 compose(Transformer)。它和 lift() 的区别在于, lift() 是针对事件项和事件序列的,而 compose() 是针对 Observable 自身进行变换。举个例子,假设在程序中有多个 Observable ,并且他们都需要应用一组相同的 lift() 变换。你可以这么写:

    observable1

    .lift1()

    .lift2()

    .lift3()

    .lift4()

    .subscribe(subscriber1);

    observable2

    .lift1()

    .lift2()

    .lift3()

    .lift4()

    .subscribe(subscriber2);

    observable3

    .lift1()

    .lift2()

    .lift3()

    .lift4()

    .subscribe(subscriber3);

    observable4

    .lift1()

    .lift2()

    .lift3()

    .lift4()

    .subscribe(subscriber1);

    你觉得这样太不软件工程了,于是你改成了这样:

    private Observable liftAll(Observable observable) {

    return observable

    .lift1()

    .lift2()

    .lift3()

    .lift4();

    }

    ...

    liftAll(observable1).subscribe(subscriber1);

    liftAll(observable2).subscribe(subscriber2);

    liftAll(observable3).subscribe(subscriber3);

    liftAll(observable4).subscribe(subscriber4);

    可读性、可维护性都提高了。可是 Observable 被一个方法包起来,这种方式对于 Observale 的灵活性似乎还是增添了那么点限制。怎么办?这个时候,就应该用 compose() 来解决了:

    public class LiftAllTransformerimplements Observable.Transformer {

    @Override

        public Observable call(Observable observable) {

    return observable

    .lift1()

    .lift2()

    .lift3()

    .lift4();

    }

    }

    ...

    Transformer liftAll =new LiftAllTransformer();

    observable1.compose(liftAll).subscribe(subscriber1);

    observable2.compose(liftAll).subscribe(subscriber2);

    observable3.compose(liftAll).subscribe(subscriber3);

    observable4.compose(liftAll).subscribe(subscriber4);

    像上面这样,使用 compose() 方法,Observable 可以利用传入的 Transformer 对象的 call 方法直接对自身进行处理,也就不必被包在方法的里面了。

    谢谢大哥们的观赏,小弟初来乍到,有什么错误谢谢指导,感激不尽

    相关文章

      网友评论

          本文标题:Android RxJava + lambda 的使用

          本文链接:https://www.haomeiwen.com/subject/kfnugxtx.html