您的位置:首页 > 移动开发 > Android开发

初涉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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: