Android RxJava + lambda 的使用

使用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 方法直接对自身进行处理,也就不必被包在方法的里面了。


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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容