- 浏览: 2216476 次
- 性别:
- 来自: 北京
-
文章分类
- 全部博客 (1240)
- mac/IOS (287)
- flutter (1)
- J2EE (115)
- android基础知识 (582)
- android中级知识 (55)
- android组件(Widget)开发 (18)
- android 错误 (21)
- javascript (18)
- linux (70)
- 树莓派 (18)
- gwt/gxt (1)
- 工具(IDE)/包(jar) (18)
- web前端 (17)
- java 算法 (8)
- 其它 (5)
- chrome (7)
- 数据库 (8)
- 经济/金融 (0)
- english (2)
- HTML5 (7)
- 网络安全 (14)
- 设计欣赏/设计窗 (8)
- 汇编/C (8)
- 工具类 (4)
- 游戏 (5)
- 开发频道 (5)
- Android OpenGL (1)
- 科学 (4)
- 运维 (0)
- 好东西 (6)
- 美食 (1)
最新评论
-
liangzai_cool:
请教一下,文中,shell、C、Python三种方式控制led ...
树莓派 - MAX7219 -
jiazimo:
...
Kafka源码分析-序列5 -Producer -RecordAccumulator队列分析 -
hp321:
Windows该命令是不是需要安装什么软件才可以?我试过不行( ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
hp321:
Chenzh_758 写道其实直接用一下代码就可以解决了:JP ...
ImageIO读jpg的时候出现javax.imageio.IIOException: Unsupported Image Type -
huanghonhpeng:
大哥你真强什么都会,研究研究。。。。小弟在这里学到了很多知识。 ...
android 浏览器
原文链接
在第1,2,3篇中,我大概介绍了RxJava是怎么使用的。下面我会介绍如何在Android中使用RxJava.
RxAndroid
RxAndroid是RxJava的一个针对Android平台的扩展。它包含了一些能够简化Android开发的工具。
首先,AndroidSchedulers提供了针对Android的线程系统的调度器。需要在UI线程中运行某些代码?很简单,只需要使用AndroidSchedulers.mainThread():
如果你已经创建了自己的Handler,你可以使用HandlerThreadScheduler1将一个调度器链接到你的handler上。
接着要介绍的就是AndroidObservable,它提供了跟多的功能来配合Android的生命周期。bindActivity()和bindFragment()方法默认使用AndroidSchedulers.mainThread()来执行观察者代码,这两个方法会在Activity或者Fragment结束的时候通知被观察者停止发出新的消息。
我自己也很喜欢AndroidObservable.fromBroadcast()方法,它允许你创建一个类似BroadcastReceiver的Observable对象。下面的例子展示了如何在网络变化的时候被通知到:
最后要介绍的是ViewObservable,使用它可以给View添加了一些绑定。如果你想在每次点击view的时候都收到一个事件,可以使用ViewObservable.clicks(),或者你想监听TextView的内容变化,可以使用ViewObservable.text()。
Retrofit
大名鼎鼎的Retrofit库内置了对RxJava的支持。通常调用发可以通过使用一个Callback对象来获取异步的结果:
使用RxJava,你可以直接返回一个Observable对象。
现在你可以随意使用Observable对象了。你不仅可以获取数据,还可以进行变换。
Retrofit对Observable的支持使得它可以很简单的将多个REST请求结合起来。比如我们有一个请求是获取照片的,还有一个请求是获取元数据的,我们就可以将这两个请求并发的发出,并且等待两个结果都返回之后再做处理:
在第二篇里我展示过一个类似的例子(使用flatMap())。这里我只是想展示以下使用RxJava+Retrofit可以多么简单地组合多个REST请求。
遗留代码,运行极慢的代码
Retrofit可以返回Observable对象,但是如果你使用的别的库并不支持这样怎么办?或者说一个内部的内码,你想把他们转换成Observable的?有什么简单的办法没?
绝大多数时候Observable.just() 和 Observable.from() 能够帮助你从遗留代码中创建 Observable 对象:
上面的例子中如果oldMethod()足够快是没有什么问题的,但是如果很慢呢?调用oldMethod()将会阻塞住他所在的线程。
为了解决这个问题,可以参考我一直使用的方法–使用defer()来包装缓慢的代码:
现在,newMethod()的调用不会阻塞了,除非你订阅返回的observable对象。
生命周期
我把最难的不分留在了最后。如何处理Activity的生命周期?主要就是两个问题:
1.在configuration改变(比如转屏)之后继续之前的Subscription。
比如你使用Retrofit发出了一个REST请求,接着想在listview中展示结果。如果在网络请求的时候用户旋转了屏幕怎么办?你当然想继续刚才的请求,但是怎么搞?
2.Observable持有Context导致的内存泄露
这个问题是因为创建subscription的时候,以某种方式持有了context的引用,尤其是当你和view交互的时候,这太容易发生!如果Observable没有及时结束,内存占用就会越来越大。
不幸的是,没有银弹来解决这两个问题,但是这里有一些指导方案你可以参考。
第一个问题的解决方案就是使用RxJava内置的缓存机制,这样你就可以对同一个Observable对象执行unsubscribe/resubscribe,却不用重复运行得到Observable的代码。cache() (或者 replay())会继续执行网络请求(甚至你调用了unsubscribe也不会停止)。这就是说你可以在Activity重新创建的时候从cache()的返回值中创建一个新的Observable对象。
注意,两次sub是使用的同一个缓存的请求。当然在哪里去存储请求的结果还是要你自己来做,和所有其他的生命周期相关的解决方案一延虎,必须在生命周期外的某个地方存储。(retained fragment或者单例等等)。
第二个问题的解决方案就是在生命周期的某个时刻取消订阅。一个很常见的模式就是使用CompositeSubscription来持有所有的Subscriptions,然后在onDestroy()或者onDestroyView()里取消所有的订阅。
你可以在Activity/Fragment的基类里创建一个CompositeSubscription对象,在子类中使用它。
注意! 一旦你调用了 CompositeSubscription.unsubscribe(),这个CompositeSubscription对象就不可用了, 如果你还想使用CompositeSubscription,就必须在创建一个新的对象了。
两个问题的解决方案都需要添加额外的代码,如果谁有更好的方案,欢迎告诉我。
总结
RxJava还是一个很新的项目,RxAndroid更是。RxAndroid目前还在活跃开发中,也没有多少好的例子。我打赌一年之后我的一些建议就会被看做过时了。
在第1,2,3篇中,我大概介绍了RxJava是怎么使用的。下面我会介绍如何在Android中使用RxJava.
RxAndroid
RxAndroid是RxJava的一个针对Android平台的扩展。它包含了一些能够简化Android开发的工具。
首先,AndroidSchedulers提供了针对Android的线程系统的调度器。需要在UI线程中运行某些代码?很简单,只需要使用AndroidSchedulers.mainThread():
retrofitService.getImage(url) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(bitmap -> myImageView.setImageBitmap(bitmap));
如果你已经创建了自己的Handler,你可以使用HandlerThreadScheduler1将一个调度器链接到你的handler上。
接着要介绍的就是AndroidObservable,它提供了跟多的功能来配合Android的生命周期。bindActivity()和bindFragment()方法默认使用AndroidSchedulers.mainThread()来执行观察者代码,这两个方法会在Activity或者Fragment结束的时候通知被观察者停止发出新的消息。
AndroidObservable.bindActivity(this, retrofitService.getImage(url)) .subscribeOn(Schedulers.io()) .subscribe(bitmap -> myImageView.setImageBitmap(bitmap);
我自己也很喜欢AndroidObservable.fromBroadcast()方法,它允许你创建一个类似BroadcastReceiver的Observable对象。下面的例子展示了如何在网络变化的时候被通知到:
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); AndroidObservable.fromBroadcast(context, filter) .subscribe(intent -> handleConnectivityChange(intent));
最后要介绍的是ViewObservable,使用它可以给View添加了一些绑定。如果你想在每次点击view的时候都收到一个事件,可以使用ViewObservable.clicks(),或者你想监听TextView的内容变化,可以使用ViewObservable.text()。
ViewObservable.clicks(mCardNameEditText, false) .subscribe(view -> handleClick(view));
Retrofit
大名鼎鼎的Retrofit库内置了对RxJava的支持。通常调用发可以通过使用一个Callback对象来获取异步的结果:
@GET("/user/{id}/photo") void getUserPhoto(@Path("id") int id, Callback<Photo> cb);
使用RxJava,你可以直接返回一个Observable对象。
@GET("/user/{id}/photo") Observable<Photo> getUserPhoto(@Path("id") int id);
现在你可以随意使用Observable对象了。你不仅可以获取数据,还可以进行变换。
Retrofit对Observable的支持使得它可以很简单的将多个REST请求结合起来。比如我们有一个请求是获取照片的,还有一个请求是获取元数据的,我们就可以将这两个请求并发的发出,并且等待两个结果都返回之后再做处理:
Observable.zip( service.getUserPhoto(id), service.getPhotoMetadata(id), (photo, metadata) -> createPhotoWithData(photo, metadata)) .subscribe(photoWithData -> showPhoto(photoWithData));
在第二篇里我展示过一个类似的例子(使用flatMap())。这里我只是想展示以下使用RxJava+Retrofit可以多么简单地组合多个REST请求。
遗留代码,运行极慢的代码
Retrofit可以返回Observable对象,但是如果你使用的别的库并不支持这样怎么办?或者说一个内部的内码,你想把他们转换成Observable的?有什么简单的办法没?
绝大多数时候Observable.just() 和 Observable.from() 能够帮助你从遗留代码中创建 Observable 对象:
private Object oldMethod() { ... } public Observable<Object> newMethod() { return Observable.just(oldMethod()); }
上面的例子中如果oldMethod()足够快是没有什么问题的,但是如果很慢呢?调用oldMethod()将会阻塞住他所在的线程。
为了解决这个问题,可以参考我一直使用的方法–使用defer()来包装缓慢的代码:
private Object slowBlockingMethod() { ... } public Observable<Object> newMethod() { return Observable.defer(() -> Observable.just(slowBlockingMethod())); }
现在,newMethod()的调用不会阻塞了,除非你订阅返回的observable对象。
生命周期
我把最难的不分留在了最后。如何处理Activity的生命周期?主要就是两个问题:
1.在configuration改变(比如转屏)之后继续之前的Subscription。
比如你使用Retrofit发出了一个REST请求,接着想在listview中展示结果。如果在网络请求的时候用户旋转了屏幕怎么办?你当然想继续刚才的请求,但是怎么搞?
2.Observable持有Context导致的内存泄露
这个问题是因为创建subscription的时候,以某种方式持有了context的引用,尤其是当你和view交互的时候,这太容易发生!如果Observable没有及时结束,内存占用就会越来越大。
不幸的是,没有银弹来解决这两个问题,但是这里有一些指导方案你可以参考。
第一个问题的解决方案就是使用RxJava内置的缓存机制,这样你就可以对同一个Observable对象执行unsubscribe/resubscribe,却不用重复运行得到Observable的代码。cache() (或者 replay())会继续执行网络请求(甚至你调用了unsubscribe也不会停止)。这就是说你可以在Activity重新创建的时候从cache()的返回值中创建一个新的Observable对象。
Observable<Photo> request = service.getUserPhoto(id).cache(); Subscription sub = request.subscribe(photo -> handleUserPhoto(photo)); // ...When the Activity is being recreated... sub.unsubscribe(); // ...Once the Activity is recreated... request.subscribe(photo -> handleUserPhoto(photo));
注意,两次sub是使用的同一个缓存的请求。当然在哪里去存储请求的结果还是要你自己来做,和所有其他的生命周期相关的解决方案一延虎,必须在生命周期外的某个地方存储。(retained fragment或者单例等等)。
第二个问题的解决方案就是在生命周期的某个时刻取消订阅。一个很常见的模式就是使用CompositeSubscription来持有所有的Subscriptions,然后在onDestroy()或者onDestroyView()里取消所有的订阅。
private CompositeSubscription mCompositeSubscription = new CompositeSubscription(); private void doSomething() { mCompositeSubscription.add( AndroidObservable.bindActivity(this, Observable.just("Hello, World!")) .subscribe(s -> System.out.println(s))); } @Override protected void onDestroy() { super.onDestroy(); mCompositeSubscription.unsubscribe(); }
你可以在Activity/Fragment的基类里创建一个CompositeSubscription对象,在子类中使用它。
注意! 一旦你调用了 CompositeSubscription.unsubscribe(),这个CompositeSubscription对象就不可用了, 如果你还想使用CompositeSubscription,就必须在创建一个新的对象了。
两个问题的解决方案都需要添加额外的代码,如果谁有更好的方案,欢迎告诉我。
总结
RxJava还是一个很新的项目,RxAndroid更是。RxAndroid目前还在活跃开发中,也没有多少好的例子。我打赌一年之后我的一些建议就会被看做过时了。
发表评论
-
带你深入理解 FLUTTER 中的字体“冷”知识
2020-08-10 23:40 656本篇将带你深入理解 Flutter 开发过程中关于字体和文 ... -
Flutter -自定义日历组件
2020-03-01 17:56 1133颜色文件和屏幕适配的文件 可以自己给定 import ... -
Dart高级(一)——泛型与Json To Bean
2020-02-23 19:13 1024从 Flutter 发布到现在, 越来越多人开始尝试使用 Da ... -
flutter loading、Progress进度条
2020-02-21 17:03 1201Flutter Progress 1 条形无固定值进度条 ... -
Flutter使用Https加载图片
2020-02-21 01:39 1045Flutter使用Https加载图片 使用http加载图片出 ... -
flutter shared_preferences 异步变同步
2020-02-21 00:55 864前言 引用 在开发原生iOS或Native应用时,一般有判断上 ... -
Flutter TextField边框颜色
2020-02-19 21:31 956监听要销毁 myController.dispose(); T ... -
flutter Future的正确用法
2020-02-18 21:55 816在flutter中经常会用到异步任务,dart中异步任务异步处 ... -
记一次Flutter简单粗暴处理HTTPS证书检验方法
2020-02-18 14:13 1008最近在做Flutter项目到了遇到一个无解的事情,当使用Ima ... -
flutter 获取屏幕宽度高度 通知栏高度等屏幕信息
2019-07-27 08:39 1369##MediaQuery MediaQuery.of(con ... -
关于flutter RefreshIndicator扩展listview下拉刷新的问题
2019-07-10 19:40 1158当条目过少时listview某些嵌套情况下可能不会滚动(条目 ... -
flutter listview 改变状态的时候一直无限添加
2019-07-10 16:01 817setstate的时候会一直无限的调用listview.bui ... -
Flutter Android端启动白屏问题的解决
2019-07-09 00:51 1548问题描述 Flutter 应用在 Android 端上启动时 ... -
Flutter中SnackBar使用
2019-07-08 23:43 800底部弹出,然后在指定时间后消失。 注意: build(Bui ... -
Flutter 之点击空白区域收起键盘
2019-07-08 18:43 1806点击空白处取消TextField焦点这个需求是非常简单的,在学 ... -
Flutter 弹窗 Dialog ,AlertDialog,IOS风格
2019-07-08 18:04 1403import 'package:flutter/mate ... -
flutter ---TextField 之 输入类型、长度限制
2019-07-08 14:30 2362TextField想要实现输入类型、长度限制需要先引入impo ... -
【flutter 溢出BUG】键盘上显示bottom overflowed by 104 PIXELS
2019-07-08 11:13 1602一开始直接使用Scaffold布局,body:new Colu ... -
解决Flutter项目卡在Initializing gradle...界面的问题
2019-07-07 12:53 907Flutter最近很火,我抽出了一点时间对Flutter进行了 ... -
关于android O 上 NotificationChannel 的一些注意事项
2019-07-04 11:47 954最近在适配android O,遇到个问题,应用中原本有设置界面 ...
相关推荐
)深入浅出RxJava(三--响应式的好处)深入浅出RxJava(四-在Android中使用响应式编程)如何升级到RxAndroid1.0 -适合使用Rx 0.x版本的用户升级的时候参考可能是东半球最全的 RxJava 使用场景小结RxJava系列1(简介)...
《给 Android 开发者的 RxJava 详解》这本书深入浅出地介绍了如何在 Android 开发环境中应用 RxJava 这个强大的响应式编程库。RxJava 是一个用于处理异步数据流和事件流的库,它引入了函数式编程的概念,使得复杂的...
首先,RxJava是一种响应式编程库,它为异步编程提供了简洁且强大的工具。响应式编程的核心理念是数据流(数据序列)和变化传播,允许开发者以声明式的方式处理事件和数据。RxJava提供了Observable(被观察者)和...
《台湾高人高焕堂Android完整讲义》是一份深入浅出的Android开发教程,涵盖了Android平台的基础知识、核心框架结构解析以及高级整合开发技术。这份讲义旨在帮助开发者全面理解Android系统的运作机制,提升在Android...
《Android网络开发与应用实战详解》一书深入浅出地介绍了Android系统中如何实现网络通信,并提供了丰富的源码示例。这本书涵盖的内容广泛,包括基础的HTTP请求、数据解析、网络状态管理以及高级的WebSocket通信和...
根据给定文件信息,本篇文档是关于Android研发工程师高级进阶技能的介绍,涉及了函数响应式编程、Android Support Annotations、RxJava、Android应用性能优化、Fragment使用、依赖注入、ASCE1885动态启发技术等技术...
《Android开发艺术探索》这本书是Android开发者们非常推崇的一本技术书籍,它深入浅出地讲解了Android开发的各种技术和实践。这份"《Android开发艺术探索》源码.zip"压缩包包含的是书中所有章节的源代码,这对于学习...
9. **响应式编程**:响应式编程如RxJava和LiveData的使用,可以帮助开发者处理异步操作和数据流。周报可能会讨论如何在Android应用中实现响应式架构。 10. **最新框架与库**:Android社区中不断涌现出新的开源库,...
10. **Android框架与库**: Mars的教程可能使用了诸如ButterKnife、Dagger2等依赖注入工具,以及RxJava进行响应式编程,帮助提升代码质量和可维护性。 11. **单元测试与持续集成**:了解如何使用JUnit、Espresso...
在本书中,作者深入浅出地讲解了Android开发的基础知识,包括Android应用程序架构、UI设计、数据存储、网络通信、多媒体处理、传感器应用等关键领域。每个章节都配有相应的案例,这些案例的源码包含在"各章案例"中,...
李兴华老师是Android开发领域的知名专家,他的讲解深入浅出,实践性强,适合初学者和有一定经验的开发者学习。 在PPT课件中,我们可以预见到以下几个关键知识点的详细讲解: 1. **Android系统架构**:首先,课件...
这本书深入浅出地讲解了Android应用中的多线程技术,帮助开发者提升应用性能,避免常见陷阱,以及优化用户体验。 在Android系统中,由于其独特的运行环境和硬件限制,正确理解和运用线程管理至关重要。本书首先会...
在Mars的视频教学中,他将这些知识点结合实际案例进行深入浅出的讲解,并提供了相应的源码供学习者实践。通过对照源码学习,可以加深对每个知识点的理解,提高实际开发中的问题解决能力。对于想要系统学习Android...
《Android应用开发详解》这本书是Android开发者们的重要参考资料,它深入浅出地讲解了Android应用开发的各个环节。配套光盘中的源代码则是书本理论知识的实践体现,为读者提供了丰富的实例,帮助理解和掌握Android...
《Android应用开发揭秘》是一本深受开发者欢迎的书籍,它深入浅出地讲解了Android应用开发的各个环节,从基础到高级,涵盖了丰富的知识点。源码是书籍内容的实践部分,对于学习者来说,通过阅读和分析这些源码,能够...
RxJava是支持响应式编程的库,其内部广泛使用泛型来实现异步数据流的链式调用和类型安全。 ### 第二章 注解深入浅出 **注解(ANNOTATIONS)** 注解在Java中用于提供元数据,可以用于声明、描述或修改程序的行为和...