RxAndroid使用解析以及使用场景分析



先说一些废话,接触RxAndroid也有一段时间了,从刚开始知道有这么一个开源框架到使用也遇到过不少问题,下面来一一说明一下。

我们可以带着以下几个问题来了解RxAndroid,这也是我刚开始了解一些新的东西的时候常常问自己的问题,问:

1、在刚接触RxAndroid的时候,最想知道的是这个东西是什么?

2、我们为什么要用他,他比现存的机制好在哪里?

3、他有哪些优点?

通过一段时间的学习,我们可以先简短的回答上面几个问题,答:

1、RxAndroid是一款响应式的编程框架,他的基本思想还是基于观察者和订阅者模式。

2、我们现存的机制有Handler异步消息处理机制,asyncTask。他们有一个共同点,代码不够整洁,也比较散乱,比如在一个Activty中随处可以看到他们,不理于开发和维护。还有就是异步消息处理起来比较繁琐。

3、可以把调用和响应分开,代码量利于管理。可以多个订阅者,一个被观察者,所以可以实现多个网络调用。利用Map方式可以把要处理的数据进行转换。可以使用UI线程处理,也可以选择io线程处理数据。

下面我们正式开始介绍RxAndroid,RxAndroid最重要的两个类就是Subscriber(订阅者)和Observable(被观察者)。

下面我们通过代码才看一下他们的使用:

public class MainActivity extends AppCompatActivity {
  
    private Button btn_send;
    //被观察者
    Observable<Integer> observable;
    //订阅者
    Subscriber<String> subscriber;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
	//初始化一个订阅者
        createSubscriber();
	//初始化一个按钮,点击后进行绑定并发送数据
        btn_send = (Button) findViewById(R.id.btn_send);
        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                createObservable();
            }
        });
    }
    //初始化一个订阅者	
    public void createSubscriber() {
        subscriber = new Subscriber<String>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(String s) {

            }
        };
    }


    //创建一个被观察者  	
    private void createObservable() {
        observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {//绑定完成会会自动调用此方法,可以在这里做一些网络请求等操作
                //我们直接通知被观察者
                subscriber.onNext("haha");
                subscriber.onCompleted();
            }
        });

        bindSubscriber();
    }
    //被观察者绑定订阅者
    private void bindSubscriber() {
        observable.subscribe(subscriber);
    }

代码解读,首先我们先初始化一个Subscriber(订阅者),发btn_send按钮被点击的时候,我们会先初始化一个Observable(被观察者),然后将Observable和Subscriber绑定以后,会自动调用Observable的call的回调方法。在这个方法里面我们可以做一些同步或异步的操作,网络请求,数据库操作等等。我们的demo是个简单的例子,我们直接就回调订阅者的onNext方法和onCompleted方法。整个流程的简单使用到此结束,相信大家一看代码不用看解读都能明白的。

也有人肯定会说,这不就是一个接口回调嘛,我们自己写也一样的。如果从最简单的角度上讲,我认为的确是这样的。接下来我们会对RxAndroid的使用进行更深入的讲解。

在这里先介绍两个接口Func,Action。Func是有返回值的,适用于一些需要返回值的地方,而Action是没有返回值的,适用于执行一些代码不需要其返回结果的。

上面的demo中我们介绍到Observable可以绑定Subscriber并在Observable的方法中进行回调通知观察者(Subscriber),现在还有一种用法是Observable只需要绑定了Func或者是Action,那么Func或者Action中的call方法就会自动被执行。他的作用是将我们在一个方法中调用另外一个方法,导致一个方法被多个地方调用,改动被调用代码,调用的地方太多,可能在不知道的情况下会对调用者产生影响。而我们RxAndroid将这些调用的位置放到一起,更便于我们代码的阅读和维护。

示例代码说明一下:

  private Action1<String> mAction1 = new Action1<String>() {
        @Override public void call(String s) {
            Toast.makeText(MoreActivity.this, s, Toast.LENGTH_SHORT).show();
        }
    };

 
    private Func1<List<String>, String> mFunc2 = new Func1<List<String>, Observable<String>>() {
        @Override public Observable<String> call(List<String> strings) {
            return "11"; 
	    }
    };
observable.subscribe(mFunc2).subscribe(mAction1);

这个时候就会优先调用mAction2的回调方法,然后将返回的值给mAction1的回调方法call(String)。这样就可以将多个方法的调用或者功能处理上暴露在一个observable,更便于我们代码的管理。

下面我们介绍一个和上面observable绑定Func和Action接口类似功能的方法,Map

这个Map和我们JAVA中常使用的Map在的功能还不一样,不过使用方式有点类似,也是以<K,Y的方式存在的>。Map<K,Y>中的K代码输入参数的类似,V代表返回的数据的类型,下面我们一起看一下它的使用

 observable = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {

                subscriber.onNext("11.22");
                subscriber.onCompleted();
            }
        }).map(new Func1<String, Double>() {
            @Override
            public Double call(String s) {
                return Double.parseDouble(s);
            }
        }).map(new Func1<Double, Integer>() {
            @Override
            public Integer call(Double integer) {
                return integer.intValue();
            }
        });

通过代码可以看出Map其实也就是在内部使用了Func而已,只不过是强制使用的。而我们可以选择使用Map也可以直接使用Func或者Action,看个人用途了。

提到Map还有一个和Map相关的方法flatMap,Map主要用于对数据类型的转换,而flatMap主要用于当observable绑定数据为数组的时候,可以配合from对此进行迭带的同时进行数据转换,而且flat返回值为observable<T>,这个时候如果数据多层嵌套,可以再次使用flatMap还可以对数据进行进一步的剥离。

同时介绍一下from,from主要是将其他种类的对象和数据类型转换为Observable,在此后面使用Func或者Action可以对数据进行迭代,看一下下面的用法就一目了然

首先先简单的看一下from的简单使用

    public static void from(){
        Integer [] items={1,2,3,4,5,6,7,8,9};
        Observable observable = Observable.from(items);
        observable.subscribe(new Action1() {
            @Override public void call(Object o) {
                Log.i("adu",o.toString());
            }
        });
    }
    打印结果:1 2 3 4 5 6 7 8 9 
其实from的简单使用就和我们遍历集合一样。

下面再一看一组from和flatMap的结合使用

private void ObservableFlatMap() {
        String[] arrs = new String[]{"aa", "bb"};
        String[] strings = new String[]{"a", "b", "c"};

        Observable observable= Observable
                .from(arrs);
        observable
                .map(new Func1<String[], Observable<String>>() {
                    @Override
                    public Observable<String> call(String[] strings) {
                        return Observable.from(strings);
                    }
                }).map(new Func1<String, Observable<String>>() {
		    @Override
		    public Observable<String> call(String s) {
			return null;
		    }
        });
    }
在此可以非常明显的看出 flat每次都会返回Observable<T>供我们下次使用,非常适合数据的多层嵌套解析使用。


下面来说一下just的使用,just主要使用场合在哪里呢,他直接去除掉了observabled关于call的回调,直接发射数据到

Subscriber(订阅者),执行onNext方法并把数据传进行,执行完成后调用onCompleted的回调。just方法中可以接收普通变量,也可以接收数组

Integer[] items1={1,2,3,4,5};
        Integer[] items2={4,5,1,6,0};
        //Observable<Integer[]> observable1 = Observable.just(items1,items2);just方法中可以接收普通变量,也可以接收数组
	//Observable<Integer> observable1 = Observable.just(1,2);

        Subscriber<Integer[]> subscriber1 = new Subscriber<Integer[]>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer[] o) {
                
            }
        };
        observable1.subscribe(subscriber1);
intervalRxAndroid中还有和我们Handler中做定时器类似的接口  interval ,interval操作符既可以延迟执行一段逻辑 ,由于使用比较简单直接上代码更清晰点

 Observable observable = Observable.interval(1,1, TimeUnit.SECONDS);//每隔一秒发送数据
            observable.subscribe(new Action1() {
                @Override public void call(Object o) {
                    Log.i("adu",o.toString());
                }
            });

filter数据过滤

    /**
     * 根据条件过滤数据
     */
    public static void filter(){
        Observable observable = Observable.just(10,9,8,7,6,7,4);
        observable.filter(new Func1<Integer,Boolean>() {
            @Override public Boolean call(Integer integer) {
                return integer>8;//过滤条件
            }
        }).observeOn(Schedulers.io()).subscribe(new Subscriber<Integer>() {
            @Override public void onCompleted() {
                Log.i(TAG,"onCompleted");
            }
            @Override public void onError(Throwable e) {
                Log.i(TAG,"onError");
            }
            @Override public void onNext(Integer integer) {
                Log.i(TAG,"inNext==》》"+integer);
            }
        });
    }
下面是一些我们常用的方法
observables 被观察者(事件源) 
subscribers 观察者 
subscribeOn()让我们在指定线程中运行获取数据的代码,只要不是UI线程就行。值有
.immediate() :默认状态,哪用算哪
.newThread(): 开新线程做这件事
.io(): 跟newThread()差不多,不过在线程池大小上有差异,他是无限大
.computation():跟创建固定的线程池操作
.mainThread():在主线程做事
observeOn()让我们在合适的线程中接收Observable发送的数据,在这里是UI主线程。
fromCallable()方法可以拖延Observable获取数据的操作,这一点在数据需要在其他线程获取时尤其重要。
schedulers 子线程、主线程切换的调度 器,schedulers.newThread() 在子线程中执行,schedulers.mainThread()在主线程中执行,还有io(),computation(),immediate() 
map 用来操作observable和最终的subscriber之间修改observable发出事件的类型,比如发出类型为int类型,最终为String类型,中间用map来转换 
from 能够达到遍历数组的效果,将数组中的元素依次显示 
filter 得到大于或者小于某个数的值 
take得到前几位值 
takelast得到后几位值 
deitinct 对一个值只处理一次

最后记得,如果你要退出页面了,一定要记得解除他们的绑定关系,否则可能会出现意想不到的错误

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (subscriber!=null&&!subscriber.isUnsubscribed()){
            subscriber.unsubscribe();//取消订阅关系,
        }
    }





  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值