美文网首页
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