大飞

大飞 关注TA

挑战一切!

大飞

大飞

关注TA

挑战一切!

  •  世界的顶端
  • 混口饭吃
  • 写了333,609字

该文章投稿至Nemo社区   Android  板块 复制链接


rxjava 笔记

发布于 2017/05/26 23:19 1,514浏览 0回复 8,365

 

一.    Rxjava 在android中应用已经非常广泛了,下面举了一些常用到的例子

1.  与retrofit结合的网络请求

2.  取代evenbus的rxjava

3.  权限申请

4.  遍历文件

5.  合并请求,依赖请求

6.  取代handler asyntask的异步任务

7.  多级缓存

8.  定时器

二.    Rxjava 的基本概念

Observable:发射源,英文释义“可观察的”,在观察者模式中称为“被观察者”或“可观察对象”;

 

Observer:接收源,英文释义“观察者”,没错!就是观察者模式中的“观察者”,可接收Observable、Subject发射的数据;

Subject:Subject是一个比较特殊的对象,既可充当发射源,也可充当接收源

Subscriber:“订阅者”,也是接收源,那它跟Observer有什么区别呢?Subscriber实现了Observer接口,比Observer多了一个最重要的方法unsubscribe( ),用来取消订阅,当你不再想接收数据了,可以调用unsubscribe( )方法停止接收,Observer 在 subscribe() 过程中,最终也会被转换成 Subscriber 对象,一般情况下,建议使用Subscriber作为接收源;

Subscription :Observable调用subscribe( )方法返回的对象,同样有unsubscribe( )方法,可以用来取消订阅事件;

Action0:RxJava中的一个接口,它只有一个无参call()方法,且无返回值,同样还有Action1,Action2...Action9等,Action1封装了含有 1 个参的call()方法,即call(T t),Action2封装了含有 2 个参数的call方法,即call(T1 t1,T2 t2),以此类推;

Func0:与Action0非常相似,也有call()方法,但是它是有返回值的,同样也有Func0、Func1...Func9;

 

三.    Rxjava 的对比学习

基本实现步骤:创建被观察者,创建观察者,订阅

Rxjava实现代码上的简洁而不是代码上的减少

1.  retrofit网络请求

Call<List<Blogs>> call = service.getBlog(1);//获取服务

call.enqueue(new Callback< List<Blogs>>() {

    @Override

    public void onResponse(Call< List<Blogs>> call, Response< List<Blogs>> response) {

        try {

           System.out.println(response.body().string());

        } catch (IOException e) {

            e.printStackTrace(); }

}

    @Override

public void onFailure(Call<ResponseBody> call, Throwable t) {   

 t.printStackTrace();   }

}

);

与rxjava结合的retrofit

BlogService service = retrofit.create(BlogService.class);
service.getBlogs(1)
 .subscribeOn(Schedulers.newThread())//请求网络在子线程中  被观察者
  .observeOn(AndroidSchedulers.mainThread())//回调在主线程中   观察者
.subscribe(new Subscriber< List<Blog>>() {
      @Override
      public void onCompleted() {
        System.out.println("onCompleted");
      }
 
      @Override
      public void onError(Throwable e) {
        System.err.println("onError");
      }
 
      @Override
      public void onNext(List<Blog> blogsResult) {
        System.out.println(blogsResult);
      }
  });

看起来加上rxjava更加多了几行代码,实现的效果也差不多,这好像是更不可以接受的,但是为什么那么多人使用,都是跟风吗?

认真一看,好处只有一个不使用retrofit还需要从response获取对象,而使用了rejava可以直接获取到对象了。

其实我任务还隐藏这两个好处:

加入线程控制让代码逻辑结构更加的清晰

.subscribeOn(Schedulers.newThread())//请求网络在子线程中  被观察者
  .observeOn(AndroidSchedulers.mainThread())//回调在主线程中   观察者

在数据执行到next前做一定的操作,比如排序等

   .map(new Action({
public List< Blog > call(List< Blog > blogs) {
                        for (Blog bean : blogs) {} ))

如果封装起来,这一步都可以省略,这样我们就可以优雅的使用rxjava+retrofit 可以参考我的一个项目例子:https://github.com/tzz2015/commonLib.git

2.  文件的搜索

普通的java形式

new Thread() {

    @Override

    public void run() {

        super.run();

        for (File folder : folders) {

            File[] files = folder.listFiles();

            for (File file : files) {

                if (file.getName().endsWith(".png")) {

                    final Bitmap bitmap = getBitmapFromFile(file);

                    getActivity().runOnUiThread(new Runnable() {

                        @Override

                        public void run() {

                            imageCollectorView.addImage(bitmap);

                        }

                    });

                }

            }

        }

    }

}.start();

看起来也没有什么问题,通俗易懂,就是感觉有些臃肿

下面来看看rxjava的实现方法

Observable.from(folders)

    .flatMap(new Func1<File, Observable<File>>() {

        @Override

        public Observable<File> call(File file) {   //遍历文件夹

            return Observable.from(file.listFiles());

        }

    })

    .filter(new Func1<File, Boolean>() {  //判断是否为图片

        @Override

        public Boolean call(File file) {

            return file.getName().endsWith(".png");

        }

    })

    .map(new Func1<File, Bitmap>() {  //转换成bitmap

        @Override

        public Bitmap call(File file) {

            return getBitmapFromFile(file);

        }

    })

    .subscribeOn(Schedulers.io())

    .observeOn(AndroidSchedulers.mainThread())

    .subscribe(new Action1<Bitmap>() {   //最终显示出来

        @Override

        public void call(Bitmap bitmap) {

            imageCollectorView.addImage(bitmap);

        }

});

加上注释,这代码看起来就是一条线上的东西,遍历文件夹,判断是否为文件,转换成bitmap,显示

上面使用到两个变换方法 map 和flatMap,他们两还是有其别的

1、map和flatMap都是接受一个函数作为参数(Func1)

2、map函数只有一个参数,参数一般是Func1,Func1的<I,O>I,O模版分别为输入和输出值的类型,实现Func1的call方法对I类型进行处理后返回O类型数据

3、flatMap函数也只有一个参数,也是Func1,Func1的<I,O>I,O模版分别为输入和输出值的类型,实现Func1的call方法对I类型进行处理后返回O类型数据,不过这里O为Observable类型

附上部分api:

 

  1. Creating Observables(Observable的创建操作符),比如:Observable.create()、Observable.just()、Observable.from()等等;
  2. Transforming Observables(Observable的转换操作符),比如:observable.map()、observable.flatMap()、observable.buffer()等等;
  3. Filtering Observables(Observable的过滤操作符),比如:observable.filter()、observable.sample()、observable.take()等等;
  4. Combining Observables(Observable的组合操作符),比如:observable.join()、observable.merge()、observable.combineLatest()等等;
  5. Error Handling Operators(Observable的错误处理操作符),比如:observable.onErrorResumeNext()、observable.retry()等等;
  6. Observable Utility Operators(Observable的功能性操作符),比如:observable.subscribeOn()、observable.observeOn()、observable.delay()等等;
  7. Conditional and Boolean Operators(Observable的条件操作符),比如:observable.amb()、observable.contains()、observable.skipUntil()等等;
  8. Mathematical and Aggregate Operators(Observable数学运算及聚合操作符),比如:observable.count()、observable.reduce()、observable.concat()等等;
  9. 其他如observable.toList()、observable.connect()、observable.publish()等等;

 

�1�m.4v

本文标签
 {{tag}}
点了个评