RxAndroid用法

简介:

响应式编程是一种面向数据流和变化传播的编程范式。通过Rx框架我们可以很好地使用该范式。
以下为官网对该框架的解释:
ReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.
It extends the observer pattern to support sequences of data and/or events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety, concurrent data structures, and non-blocking I/O.

rx框架扩展了观察者模式,添加相应操作符(函数),以支持对事件序列进行处理,使你可以无需关心异步编程,线程安全,非阻塞io等技术细节。

使用

以下为其中涉及到的基本概念及其使用

Observable

RxJava基于观察者模式,对其进行拓展。

Subscribers(observer,观察者)订阅事件源(Observable,被观察者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西(比如数据库查询,网络操作,按键事件等)

一个Observable可以发出零个或者多个事件,直到结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onNext()或者Subscriber.onError()结束。
另外,在没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。
通过观察者模式,我们可以在被观察者中执行网络操作等耗时的异步操作,等有结果返回时才会调用观察者的onnext方法.

基础例子:

创建observer,重写oncall方法
Observable observable= Observable.create(new Observable.OnSubscribe<String>() {
                @Override
                public void call(Subscriber<? super String> subscriber) {
                    subscriber.onNext("Hello RxAndroid !!");
                    subscriber.onCompleted();
                }
            })
创建subscriber,重写onNext,onCompleted,onError方法
Subscriber subscriber=new Subscriber<String>() {
     @Override
     public void onCompleted() {
         Log.v(TAG, "testFirst:onCompleted");
     }


     @Override
     public void onError(Throwable e) {

     }

     @Override
     public void onNext(String s) {
         Log.v(TAG, "onNext:" + s);
     }
 });
订阅
observable.subscribe(subscriber);  

小结:

rxjava基于观察者模式,可以实现对任何异步操作的回调处理。可以将observable理解成一个callable对象,在observer subscribe的时候,执行了observable的call方法,在call方法中可以执行各种异步操作,执行完以后将结果回调给subscribe的onNext方法。

Operators

rxjava的核心和难点就在于其大量的操作符,可以在http://reactivex.io/documentation/operators.html查询到所有操作符,通过这些操作符,我们可以创建observable,对observable发出的事件流进行转换,过滤事件流,合并事件流等操作。通过这些操作符,我们可以对Observable进行链式调用,直到得到我们想要传递给observer的事件。我们重点考察常用的几个操作符。

创建observable

Create

见上面的例子

From

可以将一些集合等数据结构转换为事件流,在订阅时将各个item依次发送给订阅者

List<String> test = new ArrayList<String>();
            test.add(s);
            test.add("testMap");
Observable.from(list)
Just

将一系列的对象转换为事件流,在订阅时将各个item依次发送给订阅者

Observable.just(1234)

observable转换

map

map操作符提供了对事件流的转换,以下例子为将String前面加上hello,你也可以将事件转换为任意类型。

Observable.just("coderrobin").map(new Func1<String, String>() {
      @Override
      public String call(String s) {
          return "hello"+test;
      }
  })
          .subscribe(new Action1<String>() {
              @Override
              public void call(String text) {
                  Log.v(TAG, text);
              }
          });
flatmap

flatmap提供了对observable的转换

Observable.just("coderrobin").map(new Func1<String, List>() {
     @Override
     public List<String> call(String s) {
         List<String> test = new ArrayList<String>();
         test.add(s);
         test.add("testMap");
         return test;
     }
 }).flatMap(new Func1<List, Observable<String>>() {
     @Override
     public Observable<String> call(List list) {
         return Observable.from(list);
     }
 })
         .subscribe(new Action1<String>() {
             @Override
             public void call(String text) {
                 Log.v(TAG, text);
             }
         });

flatmap的强大之处在于在转换observable时我们可以添加包括异步操作在内的各种业务逻辑。以下载一个app为例子,我们在第一个observable中通过网络获取某个app的下载地址,获取到以后传递给第二个observable,在第二个observable中进行下载操作,下载过程中通过onnext通知observer下载进度,通过onComplete通知下载完成。如果我们要自己实现上述逻辑,则需要3级回调,堪称回调地狱,而在rxjava中通过操作符的链式调用即可实现。

Buffer

聚合,将分散的事件集中为list发送给订阅者

Observable.just(1,2,3,4).buffer(2).subscribe(new Subscriber<List<Integer>>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(List<Integer> integers) {

    }
});
GroupBy,按特定规则进行分组
 Observable.just(1,2,3,4,"1","2","3",new Repo("1","1","1")).groupBy(new Func1<Object, String>() {
    @Override
    public String call(Object o) {
        if (o instanceof Number) {
            return "num";
        } else if (o instanceof String) {
            return "string";
        }
        return "other";
    }
}).subscribe(new Subscriber<GroupedObservable<String, Object>>() {
    @Override
    public void onCompleted() {

    }

    @Override
    public void onError(Throwable e) {

    }

    @Override
    public void onNext(GroupedObservable<String, Object> stringObjectGroupedObservable) {
        Log.v(TAG,stringObjectGroupedObservable.getKey());
    }
});

过滤事件

filter

filter可以对事件流进行过滤操作,对于符合条件的事件才继续往下传递

 Observable.just(1,2,3,4,5).filter(new Func1<Integer, Boolean>() {
    @Override
    public Boolean call(Integer integer) {
        return integer>3;
    }
})
        .subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer num) {
                Log.v(TAG, num+"");
            }
        }); 
distinct

过滤重复的事件,直接调用distinct方法即可

first

只获取第一个事件

合并事件流

merge

Observable odds = Observable.just(1, 3, 5).subscribeOn(someScheduler);
Observable evens = Observable.just(2, 4, 6);

Observable.merge(odds, evens)
.subscribe(new Subscriber() {
@Override
public void onNext(Integer item) {
System.out.println(“Next: “ + item);
}

    @Override
    public void onError(Throwable error) {
        System.err.println("Error: " + error.getMessage());
    }

    @Override
    public void onCompleted() {
        System.out.println("Sequence complete.");
    }
});     

错误处理

Retry

可以设置错误时重试策略
if a source Observable sends an onError notification, resubscribe to it in the hopes that it will complete without error

Schedulers

在RxAndroid中,可以通过observeOn和subscribeOn方法指定observable和observer分别工作的线程。Rx框架自动帮我们实现线程相关逻辑,无需开发者去考虑,这极大的方便了开发。

observeOn(Schedulers.newThread())
subscribeOn(AndroidSchedulers.mainThread())
如上述代码则指令被观察者在新线程中运行,观察者在主线程中运行,

demo

以下为一个为使用rxjava+Retrofit访问github api的简单例子:

Repo

public class Repo {

public String name;
public String description;
public String url;

public Repo(String name, String description, String url) {
    this.name = name;
    this.description = description;
    this.url = url;
}

public String toString() {
    return name + ": " + url;
}

}

GithubResults

public class GithubResults {
ArrayList<Repo> items;
Integer total_count;
}

GithubService

public interface GithubService {
@GET("/search/repositories")
Observable<GithubResults> getTopNewAndroidRepos(@QueryMap Map<String, String> queryMap);

}

Activity

 public void testNetwork(){
    Map<String,String> options = new HashMap<>();
    options.put("q","coderrobin");

    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint("https://api.github.com")
            .build();
    GithubService apiService = restAdapter.create(GithubService.class);
    apiService.getTopNewAndroidRepos(options)
            .observeOn(Schedulers.newThread())
            .subscribeOn(AndroidSchedulers.mainThread())
            .flatMap(new Func1<GithubResults, Observable<Repo>>() {
                @Override
                public Observable<Repo> call(GithubResults results) {
                    Log.v(TAG,results.total_count+"");

                    return Observable.from(results.items);
                }
            }).map(new Func1<Repo, String >() {
          @Override
            public String call(Repo repo) {
            return repo.url;
        }
    })
            .subscribe(new Action1<String>() {
                @Override
                public void call(String url) {
                    Log.v(TAG, "url:" + url);
                }
            });

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值