初涉RxAndroid .map() . filter() flatMap()
2016-06-06 09:58
573 查看
转载请注明出处:王亟亟的大牛之路
这周末又败家买了鱼缸和一套设备,本来预备端午出去玩玩的目测只能在家吃土,周五把之前的X项目从X的实现迁移到了RxJava(RxAndroid),这一篇也就写一下相关的知识强行安利(日更):https://github.com/ddwhan0123/Useful-Open-Source-Android
How to use?
dependencies{ compile 'io.reactivex:rxjava:1.1.5' compile 'io.reactivex:rxandroid:1.2.0' }
总共写了两个小例子,先看第一个
看下运行效果:
看下日志:
这个干了什么呢?我们有一个按钮点击之后 随机切换 image,当然图片就都是 异步下载的。
看下代码(先解释大致逻辑和第一部分,方法名命名请无视,哈哈哈)
public class TwoActivity extends AppCompatActivity implements View.OnClickListener { private Button testMap; private ImageView tiffanyImg; private RandomTools randomTools; private ArrayList<SampleModel> data; private TextView tiffanyText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_two); StatusBarCompat.compat(this, getResources().getColor(R.color.status_bar_color)); StatusBarCompat.compat(this); findId(); init(); setListener(); LogUtils.d("--->Main Thread id " + Thread.currentThread().getId()); } private void findId() { testMap = (Button) findViewById(R.id.testMap); tiffanyImg = (ImageView) findViewById(R.id.tiffanyImg); tiffanyText = (TextView) findViewById(R.id.tiffanyText); } private void init() { randomTools = RandomTools.getInstance(); //填充数据 makeSampleModelData(); } private void setListener() { testMap.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.testMap: setPhotoForOne(data); // setPhotoForTwo(data); break; } } private void setPhotoForOne(ArrayList<SampleModel> data) { Observable.just(data) .subscribeOn(Schedulers.newThread()) .map(new Func1<ArrayList<SampleModel>, SampleModel>() { @Override public SampleModel call(ArrayList<SampleModel> list) { LogUtils.d("第一个call线程id " + Thread.currentThread().getId()); //模拟返回集合的某个元素 int randInt = randomTools.getRandom(4); return list.get(randInt); } }).map(new Func1<SampleModel, String>() { @Override public String call(SampleModel sampleModel) { LogUtils.d("第二个call线程id " + Thread.currentThread().getId()); return sampleModel.getContent(); } }) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String url) { LogUtils.d("第三个call线程id " + Thread.currentThread().getId()); LogUtils.d("--->开始加载 " + url); Glide.with(TwoActivity.this).load(url).into(tiffanyImg); } }); } private void setPhotoForTwo(ArrayList<SampleModel> data) { Observable.just(data).subscribeOn(Schedulers.newThread()) .flatMap(new Func1<ArrayList<SampleModel>, Observable<SampleModel>>() { @Override public Observable<SampleModel> call(ArrayList<SampleModel> sampleModels) { return Observable.from(sampleModels); } }).filter(new Func1<SampleModel, Boolean>() { @Override public Boolean call(SampleModel sampleModel) { return !sampleModel.getName().equals(""); } }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<SampleModel>() { @Override public void onCompleted() { LogUtils.d("--->onCompleted"); } @Override public void onError(Throwable e) { LogUtils.e(e); } @Override public void onNext(SampleModel sampleModel) { LogUtils.d("--->onNext"); Glide.with(TwoActivity.this).load(sampleModel.getContent()).into(tiffanyImg); tiffanyText.setText(sampleModel.getName()); } }); } //制造数据源 private void makeSampleModelData() { data = new ArrayList<>(); data.add(new SampleModel("Tiffany one", "http://hiphotos.baidu.com/zhixin/abpic/item/4651a712c8fcc3cea97dbce49045d688d53f206c.jpg")); data.add(new SampleModel("Tiffany two", "http://pic.5442.com/2014/0930/06/5442.jpg")); data.add(new SampleModel("", "http://img5q.duitang.com/uploads/item/201410/22/20141022214043_5EEKH.thumb.224_0.jpeg")); data.add(new SampleModel("Tiffany four", "http://img5.duitang.com/uploads/item/201512/08/20151208163159_HGEM2.thumb.224_0.png")); data.add(new SampleModel("Tiffany five", "http://img4.duitang.com/uploads/item/201510/29/20151029224537_ijEKF.thumb.224_0.jpeg")); } }
首先,我们在初始化的时候打了个Thread,然后再接下来的操作力再分别打出Thread,很明显除了加载操作,别的逻辑都让他在子线程里操作,为什么?最后说,先看下去!
这一部分主要实现在于setPhotoForOne这个方法
我们给被观察者传入一个
ArrayList<SampleModel>对象,然后让他在新线程里做数据整合的一些行为
.subscribeOn(Schedulers.newThread()),接着调用了 .map方法,在这里的Func1我传入了一个键值对。
第一个参数为传入的参数 参数类型也就是
ArrayList<SampleModel>
第二个为返回的参数类型 为
SampleModel
这极大的简便了我们的操作,不再是传统的传什么返回什么,让我们的代码有更好的拓展性,事件可以分的更清楚(L表达式情况下,传统的回调地狱还是蛮烦的,但是有好有坏,一个可读性好,一个代码少)
并且可以多次调用来满足我们的业务需求,像这样
.map(new Func1<SampleModel, String>() { @Override public String call(SampleModel sampleModel) { LogUtils.d("第二个call线程id " + Thread.currentThread().getId()); return sampleModel.getContent(); } })
当然我们的UI操作,还是要回到主线程来做,不然会有异常,但是这么做的一个好处是我们的复杂操作(异步,数据库,IO等都利用多CPU的优势来降低主线程的压力) 可以达到尽量避免卡UI的情况,重要的事情说三次 避免卡UI 避免卡UI 避免卡UI
.observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<String>() { @Override public void call(String url) { LogUtils.d("第三个call线程id " + Thread.currentThread().getId()); LogUtils.d("--->开始加载 " + url); Glide.with(TwoActivity.this).load(url).into(tiffanyImg); } });
然后再来提提另外2个方法 filter() 和 flatMap()
.flatMap(new Func1<ArrayList<SampleModel>, Observable<SampleModel>>() { @Override public Observable<SampleModel> call(ArrayList<SampleModel> sampleModels) { return Observable.from(sampleModels); } })
这里的Func1也是传入2个参数
第一个为传入的类型,第二个是返回的Observable对象
和map一样他们都可以改变类型,但是只是返回的类型不同而已,大家可以根据自己的需求来选择不同的方法。
那返回的Observable又能干吗呢?
我们可以对他进行再次的嵌套,诸如二次just,二次from等等,有很大的拓展性
接下来再来提一下 .filter()
他可以为我们做“筛选”操作,
.filter(new Func1<SampleModel, Boolean>() { @Override public Boolean call(SampleModel sampleModel) { return !sampleModel.getName().equals(""); } })
false就会被过滤掉,也就是不会被观察者所执行
看下Log就清楚了
我们name为”“的那条数据就没有走onNext方法。
Ok,为什么用RxJava
1 不用再去麻烦的扣Handler做逻辑判断
2 更好的线程处理,方便好用
3 强大的API
源码地址:https://github.com/ddwhan0123/RxAndroidDemo
有问题可以WeChat我(活人,非公众号)
友情链接:http://gank.io/post/560e15be2dca930e00da1083#toc_1
相关文章推荐
- MaterialDesign_兼容性控件的使用
- Android 状态栏工具类(实现沉浸式状态栏/变色状态栏)
- Android 通用流行框架梳理
- 两个android警告
- Android_listView_exc
- 自己学习安卓时的一些繁杂的小笔记
- 报错:Binary XML file line #7: Error inflating class android.support.v7.Toolbar
- Android开源框架——图片加载库Glide
- Android4.4-Launcher源码分析系列之搜索框/删除框
- android 中XML和对象转换利器Xstream的使用
- Eclipse和Android Studio中重复性太高的代码的配置(比如:版权、作者、出处)
- activity+fragment 浅显实例的实现
- Android_常用控件及适配器
- Android开源框架Universal-Image-Loader详解
- Android_layout_note
- android布局技巧:创建高效布局
- Android环境变量笔记
- Android Layout XML属性
- Android Socket通讯基本用法
- android richEditText 可添加文本和图片的记事本功能的控件打造