RxJava学习
来源:互联网 发布:ubuntu 命令行 deb 编辑:程序博客网 时间:2024/05/18 05:01
1、首先学习rxJava必须理清楚什么是观察者,什么是被观察者?谁被谁观察?
其实是“观察者”观察“被观察者”,被观察者有什么动作会通知“观察者”,告诉他自己将要干嘛。
观察者:Observser(Subscriber)
被观察者:Observable
被观察者的创建方式,不算方法重载的话我记得好像有13种还是19种,我目前也只熟悉几种:
最基本的一种创建观察者方式:
/** * 创建被观察者方法(1):create(最基本) */ Observable observable = Observable.create(new Observable.OnSubscribe<String>() { @Override public void call(Subscriber<? super String> subscriber) { subscriber.onNext("Hello"); subscriber.onNext("RxJave"); subscriber.onCompleted(); } });以下是其他方式创建被观察者:
/** * 创建被观察者方法(2):just(快捷,将传入的参数一次发送出来) * just里面的相当于都是调用 * onNext("Hello"); * onNext("RxJava2"); * onCompleted(); */ Observable observable1 = Observable.just("Hello", "RxJava2"); /** * 创建被观察者方式3:from(T[])(传入一个数组拆分成具体对象后依次发送出来) * onNext("Hello"); * onNext("RxJava3"); * onCompleted(); */ String[] words = {"Hello", "RxJava3"}; Observable observable2 = Observable.from(words); /** * 也可以把Observer拆成三个Action单独来订阅 */ /** * Action1是RxJava的一个接口,有入参无出参 */ Action1<String> onNextAction = new Action1<String>() { @Override public void call(String s) { Log.i("MainActivity", s); } }; Action1<Throwable> onErrorAction = new Action1<Throwable>() { @Override public void call(Throwable throwable) { } }; /** * Action是RxJava的一个接口,无入参无出参,刚好适合onCompleted */ Action0 onCompletedAction = new Action0() { @Override public void call() { Log.i("MainActivity", "onCompleted"); } }; observable.subscribe(onNextAction); observable.subscribe(onErrorAction, onErrorAction); observable.subscribe(onNextAction, onErrorAction, onCompletedAction);
一个基本的Observer会实现三个方法,当然也可以只实现一个方法,如下:
/** * onError和onCompleted只会走一个 */ Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { //当事件队列执行完成的时候会走这个方法 } @Override public void onError(Throwable e) { //当执行时间队列的过程中出错会走这个方法并终止 } @Override public void onNext(String s) { //执行事件队列 } };
** * Subscriber是Observer接口的实现类,跟Observer的基本使用方式完成一样; * 实质上,rxJava在subscribe的过程中,Observer会先被转换成一个Subscriber再使用,所以如果 * 只是想使用基本功能,选择哪一个都一样; * * Subscriber与Observer的主要区别: * (1)Subscriber新增了onStart()方法,这个方法在onNext之前执行,做一些准备工作; * (2)Subscriber实现了另一个接口Subscription的方法unSubscribe(),是用来取消订阅的,当这个 * 方法被调用之后Subscriber就不再接收事件。当然取消订阅之前调用isUnsubscribed() * 先判断一下订阅状态。这个方法很重要,在Subscriber不想再收Obserable传递过来的 * 事件的时候,记得取消订阅,防止内存泄露发生。 */ Subscriber<String> subscriber = new Subscriber<String>() { @Override public void onCompleted() { Log.i("MainActivity", "onCompleted"); } @Override public void onError(Throwable e) { } @Override public void onNext(String s) { Log.i("MainActivity", s); } };
Observable被Observer(Subscriber)订阅:
observable2.subscribe(subscriber);
//场景1:打印数组 Observable.from(new String[]{"cy", "yl"}) .subscribe(new Action1<String>() { @Override public void call(String s) { Log.i("MainActivity", s); } });
rxJava很吊的原因之一就是操作符:
下面介绍一些操作符及使用场景和实例代码:
操作符之Scheduler(调度器)
/** * Schedulers 是RxJava提供的调度器, * AndroidSchedulers是rxJava提供的android专用的调度器 * .subscribeOn指定之前的操作在哪个线程中执行 * .observerOn指定之后的操作在哪个线程中执行 * * SchedulersAPI: * (1)Schedulers.immediate()直接在当前线程运行,相当于不指定线程 * (2)Schedulers.newThread()总是开启新线程,并且在新线程中运行 * (3)Schedulers.io()耗时操作就使用这个scheduler,内部是一个可复用的无上限的线程池 * (4)Schedulers.computation()专门用来做大计算的sheduler,可开线程数与cpu核数相同 * (5)AndroidSchedulers.mainThread()指定操作将在主线程中执行 */ Observable.just(1, 2, 3, 4) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { Log.i("MainActivity", integer + ""); } });其他操作符:
/** * Func1是RxJava的一个接口,有入参无出参 * 变换操作符: * .map()事件对象的直接变换(1对1变换,无法返回一个新的Obsrvable) * .flatMap()时间对象的1对多转换,可以返回一个新的Observable,可以解决循环问题(尽可能的让subscriber的操作简单化),可以用来解决嵌套请求更简单 * .concatMap()用法跟flatMap()一样,但是他有序的,flatMap是无序的。能够保证事件流保持原来的序列 * .take(4) 只取事件队列的前四个 * .taskLast(4)只去事件队列的后四个 * .distinct()过滤事件流重复发射事件 * .distinctUntilChange()过滤一样的事件直到时间发生编号才进行发射 * .repeat()按照事件队列顺序重复发射事件 * .first()只发射事件队列中第一个事件 * .last()只发射事件队列中最后一个事件 * .shkipLst(3)跳过事件队列后三个,意思就是最后三个事件不发射 * .timeout(2,TimeUnit.SECONDS)在规定时间内发射事件队列,如果总体用时超过2秒,没有发送的事件将不再发送 * .sample(2,TimeUnit.SECONDS)发射指定时间内事件流中的最后一个事件 * .throttleFirst()发射指定时间内事件流中的第一个事件 * .debounce(2,TimeUnit.SECONDS)在计时时间内事件流没有产生新事件则发送当前事件,若有新事件则重新计时 * .groupBy()根据自定义规则对事件流进行分类 * .buffer(3)将输入的事件队列,按照输入值进行分组,这个输入的是三,那么三个一组 * .doOnNext允许在输出之前,用输出的数据做其他额外的事情。但是不能阻挡数据.doOnNext(title -> saveTitle(title)) */ //map场景:就是把String对象转换成了Bitmap对象再输出 Observable.just("storage/emulated/0/Pictures/IMG_20170529_213655.jpg") .map(new Func1<String, Bitmap>() { @Override public Bitmap call(String s) { //下面的PicUtils.lessenUriImage是根据图片路径拿到图片的方法 return PicUtils.lessenUriImage(s); } }) .subscribe(new Action1<Bitmap>() { @Override public void call(Bitmap bitmap) { setBitmaoToIv(bitmap); } }); //flatMao场景1:假设输入一个学生数组,需要输出每个学生的课程名,学生的课程是多个的, // 解决办法1:可以用.from输入学生数组再拿到每个学生,根据学生遍历他的课程集合输出 List<Student> students = new ArrayList<>(); Observable.from(students) .subscribe(new Action1<Student>() { @Override public void call(Student student) { List<Course> courses = student.getCourses(); for (Course course : courses) { Log.i("MainActivity", course.getCourseName()); } } }); //解决办法2:如果不想再subscriber里面做循环,那么就这样处理 Observable.from(students) .flatMap(new Func1<Student, Observable<Course>>() { @Override public Observable<Course> call(Student student) { return Observable.from(student.getCourses()); } }) .subscribe(new Action1<Course>() { @Override public void call(Course course) { Log.i("MainActivity", course.getCourseName()); } }); //利用.from的原理(把入参一个一个输出),然后把Student的courses当做一个新的Obsevable输出 //flatMap场景2:嵌套请求,我先上传一张图片再立马把这张图片下载下来展示 viewModel.upload(countingRequestBody) .flatMap(new Func1<UploadResponse, Observable<ResponseBody>>() { @Override public Observable<ResponseBody> call(UploadResponse uploadResponse) { return viewModel.downPic(uploadResponse.file); } }) .subscribe(new Action1<ResponseBody>() { @Override public void call(ResponseBody responseBody) { Bitmap bitmap = BitmapFactory.decodeStream(responseBody.byteStream()); } }); //上面这个代码可以用lambda简化如下: viewModel.upload(countingRequestBody) .flatMap(uploadResponse -> viewModel.downPic(uploadResponse.file)) .subscribe(responseBody -> BitmapFactory.decodeStream(responseBody.byteStream()), e -> Log.i("MainActivity", e.getMessage())); RxView.clicks(findViewById(R.id.bt)) .throttleFirst(500, TimeUnit.MILLISECONDS) .subscribe(new Action1<Void>() { @Override public void call(Void aVoid) { Log.i("RxBinding", "点了"); } }); Observable.just("1", "2", "3", "4", "5") .take(3) .subscribe(new Action1<String>() { @Override public void call(String s) { Log.i("Take", s); } }); Observable.just("1", "1", "1", "2", "3", "3", "4") .distinct() .subscribe(new Action1<String>() { @Override public void call(String s) { Log.i("distinct", s); } }); Observable.just("1", "2", "3") .repeat() .subscribe(new Action1<String>() { @Override public void call(String s) { Log.i("repeat", s); } }); Observable.just(1, 2, 3, 4, 5, 6, 7) .groupBy(new Func1<Integer, Boolean>() { @Override public Boolean call(Integer integer) { return integer % 2 == 0; } }) .subscribe(new Action1<GroupedObservable<Boolean, Integer>>() { @Override public void call(GroupedObservable<Boolean, Integer> booleanIntegerGroupedObservable) { if (booleanIntegerGroupedObservable.getKey()) { //输出的是能整除2的 } else { //输出的是不能整除2的 } } });当然操作符远远不止这些。我只是做一些举例。
阅读全文
0 0
- Rxjava学习
- RxJava学习
- rxjava 学习
- RxJAVA学习
- rxJava学习
- rxjava学习
- RxJava学习
- Rxjava学习
- 学习RxJava
- Rxjava学习
- RxJava 学习
- RxJava学习
- RxJava学习
- RxJava学习
- RxJava学习笔记(1) - RxJava简介
- RxJava 学习书籍——RxJava Essentials
- RxJava学习(一),RxJava初识
- Rxjava 学习之路
- GraphHopper简介
- 数据结构与算法概念解析
- C# revit二次开发 一条语句找到所有的某种实例(一)
- android IntentService Service HandlerThread 源码解读
- 数据结构之数组
- RxJava学习
- log4j
- 安信可-A7模块——C语言编程实现GPS功能
- A+B problem(EOF)
- 当人工智能敲响了门 我们将迎来怎样的世界
- 在线api汇总,应该对你开发有帮助
- POJ 1929 Calories from Fat 笔记
- 第一次使用沃云产品
- iframe包含的页面如何能够调用到父级页面的js方法