retrofit和rxjava(加深)
Android Retrofit + RxJava使用详解(基础)
rxjava用法
subscribeOn订阅
/**
* 发送消息
*
* @param observable Observable<? extends BaseBean>
* @param urlOrigin 请求地址
*/
public void sendMessage(Observable<? extends BaseBean> observable, final String urlOrigin) {
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<BaseBean>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull BaseBean baseBean) {
Log.i("http返回:", baseBean.toString() + "");
ReceiveMessageManager.getInstance().dispatchMessage(baseBean, urlOrigin);
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
}
或者像这样
getUser(userId)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<User>() {
@Override
public void onNext(User user) {
userView.setUser(user);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable error) {
// Error handling
...
}
});
中文文档
https://mcxiaoke.gitbooks.io/rxdocs/content/
RxJava 的适用场景和使用方式
1. 与 Retrofit 的结合
http://gank.io/post/560e15be2dca930e00da1083retrofit 和网络框架之前资料汇总
https://www.zhihu.com/question/35189851
个人比较推荐Square开源组合,用Retrofit(目前已经是2.0+)+OkHttp基本上已经可以处理任何业务场景了,Square开源库质量还是值得信赖的。
Retrofit的特点我个人认为是简化了网络请求流程,同时自己内部对OkHtttp客户端做了封装,同时2.x把之前1.x版本的部分不恰当职责都转移给OkHttp了(例如Log,目前用OkHttp的Interceptor来实现),这样的好处是职责清晰,Retrofit做自己该做的事儿。
而且Retrofit提供不同的Json Converter实现(也可以自定义),同时提供RxJava支持(返回Observable对象),配合Jackson(或者Gson)和RxJava,再加上Dagger2,你的效率至少可以提高一倍。
参见我之前的回答:OkHttp在安卓中的使用? - 知乎用户的回答
目前我所在的公司的技术栈没用到Volley和android-async-http,如果要用的话,估计还是要做一下二次封装的。
同时推荐用最新的Android Flux来架构你的Android程序,Facebook提出的架构,文档比较全,数据流总是单向的,飞。用过MVC,MVP,我还是是比较认同Flux的,而且之前公司用的架构模式跟Flux也比较像
android 网络请求框架
给 Android 开发者的 RxJava 详解
RxAndroid 是 RxJava 的扩展, 优雅地处理异步请求. RxAndroid 配合 Lambda 表达式, 精简处理回调, 使程序更具有可读性. 本文详细介绍使用方法. 欢迎 Follow 我的 GitHub: https://github.com/SpikeKing
汇总
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html
Retrofit 2.0:有史以来最大的改进
http://www.2cto.com/kf/201605/510999.html
Android 网络框架 Retrofit2.0介绍、使用和封装
http://www.jcodecraeer.com/a/anzhuokaifa/2016/0325/4082.html
Retrofit使用教程(三) : Retrofit与RxJava初相逢
http://www.gekson.com/retrofitwang-luo-qing-qiu-ku-jiao-cheng/
Retrofit网络请求库教程 (对注解的说明)
http://blog.csdn.net/leilba/article/details/50685205(retrofit注解说明)
http://www.2cto.com/kf/201605/510999.html
Android 网络框架 Retrofit2.0介绍、使用和封装
http://zhaoshanshan.me/2015/09/16/Retrofit20Android%E6%9C%80%E5%A5%BD%E7%94%A8%E7%9A%84http%E5%BA%93%E6%9C%89%E5%8F%B2%E4%BB%A5%E6%9D%A5%E6%9C%80%E5%A4%A7%E7%9A%84%E6%9B%B4%E6%96%B0/
Retrofit2.0:Android最好用的http库有史以来最大的更新
如果这种解决方案还不满足,还有一种更为强大的,Retrofit+OkHttp,都是Square公司出品,然后图片加载再选择Square的Picasso(或者谷歌推荐的Glide、Facebook的Fresco)。而且,Retrofit还支持RxJava,可以使异步操作的代码更加简洁。这些搭配起来就是网络的神装了。不过Retrofit和RxJava我都没深入研究过,先打好基础再说,以后有时间再看看。
http://allenlin.leanote.com/post/volleyokhttpgson
7.19
retrofit封装网络状态
http://gank.io/post/56e80c2c677659311bed9841(封装好的 代码在c盘项目studio中的retrofitDemo)
android-async-http使用
Post的实现
private AsyncHttpClient asyncHttpClient = new AsyncHttpClient() ;
RequestParams params = new RequestParams();
params.add("version", version);
params.add("platform", Integer.toString(platform));
client.post(url, params, responseHandler);
Anroid-async-http封装网络请求框架源码分析
1)onStart() 方法是开始发送请求的时候执行的,一般是把progressDialog放在这里面显示,提示用户等待
2)onFailure() 如果请求失败了,就会执行该方法,其余方法就都不执行了,用于提示用户网络出现故障
3)onSuccess() 是请求成功后,服务器就会返回JSONObject, arg1就是返回的JSONObject, 在里面解析JSONObject来回去数据,并显示在UI上
4)onFinish() 当发送请求成功后,就执行onFinish()
===============================================================
okhttp retrofit离线缓存
Retrofit2.0+okhttp3缓存策略
Retrofit 源码解读之离线缓存策略的实现
一些你可能需要的 okhttp 实现
使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求
retrofit再度学习
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://www.BaseURL.com/") .addConverterFactory(GsonConverterFactory.create())//自动通过Gson转josn,上面有提到 .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//添加RxJava支持 .build();
Retrofit学习(一)集成-简单get请求
这个资料比较好
【Android】RxJava + Retrofit完成网络请求
RxJava
观察者模式
首先要先介绍一下观察者模式(可能比喻的不够恰当,意思到了就好);
- 观察者:监视着被观察者的行为,当被观察者某个状态改变的时候会通知观察者,观察者会执行对应的操作;
- 被观察者:被监视的对象,当某个状态改变的时候会通知观察者;
- 订阅(或注册):将观察者和被观察者建立联系。
(很乱?来个栗子?)
这里举一个我个常用的例子,点击Button后触发OnClickListener
中的onClick()事件。在这个事件中他们的角色分别如下:
- 观察者:OnClickListener;
- 被观察者:Button;
- 订阅(或注册):setOnClickListener()。
RxJava
在上面介绍了观察者模式,这里也将RxJava中的三个角色进行一下角色分配
- 观察者:Observer;
- 被观察者:Observable;
- 订阅(或注册):subscribe()。
RXjava 使用
rxjava核心功能 : 线程的准换, map
转换成不同的事件或事件序列以及
flatMap()
Subscriber
回顾下实现一次RxJava的基本使用。
例:分别打印"Hellow"、" Wrod"
Observable.just("Hello", "World").subscribe(new Subscriber<String>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(String s) {
Log.i(TAG, s);
}
});
可以看到,我们这里只用了onNext(obj),还有两个重写的onError(error)和onCompleted()并没有用到,这样导致我们多出了几行根本用不到的代码。于是就想能不能只写我们使用到的,其他几个没用到的就不写,这样的代码看着才舒服。接下来就是使用本次的主角Action来代替Subscriber
Action
上部分的代码使用Action来代替Subscriber得到的代码是这样的:
Observable.just("Hello","World").
subscribe(new Action1<String>() {
@Override public void call (String s){
Log.i(TAG, s);
}
});
舒服多了有没有!!
- 什么是Action
Action是RxJava 的一个接口,常用的有Action0和Action1。
Action0
: 它只有一个方法 call(),这个方法是无参无返回值的;由于 onCompleted() 方法也是无参无返回值的,因此 Action0 可以被当成一个包装对象,将 onCompleted() 的内容打包起来将自己作为一个参数传入 subscribe() 以实现不完整定义的回调。
Ation1
:它同样只有一个方法 call(T param),这个方法也无返回值,但有一个参数;与 Action0 同理,由于 onNext(T obj) 和 onError(Throwable error) 也是单参数无返回值的,因此 Action1 可以将 onNext(obj)和 onError(error) 打包起来传入 subscribe() 以实现不完整定义的回调
Function与Action1的区别
这里出现了一个叫做
Func1
的类。它和
Action1
非常相似,也是 RxJava 的一个接口,用于包装含有一个参数的方法。
Func1
和
Action
的区别在于,
Func1
包装的是有返回值的方法。另外,和
ActionX
一样,
FuncX
也有多个,用于不同参数个数的方法。
FuncX
和
ActionX
的区别在
FuncX
包装的是有返回值的方法。
Schedulers.io()的解释
以及参数Scheduler,RxJava已经为我们提供了一下几个Scheduler
- Schedulers.immediate():直接在当前线程运行,相当于不指定线程。这是默认的 Scheduler。
- Schedulers.newThread():总是启用新线程,并在新线程执行操作。
- Schedulers.io(): I/O 操作(读写文件、读写数据库、网络信息交互等)所使用的 Scheduler。行为模式和 newThread() 差不多,区别在于 io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。不要把计算工作放在 io() 中,可以避免创建不必要的线程。
- Schedulers.computation():计算所使用的 Scheduler。这个计算指的是 CPU 密集型计算,即不会被 I/O 等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU。
- AndroidSchedulers.mainThread():它指定的操作将在 Android 主线程运行。
【Android】RxJava的使用(四)线程控制 —— Scheduler
感觉比较经典
经典中的经典
【Android】RxJava + Retrofit完成网络请求
3、使用Observable完成一个网络请求,登录成功后保存数据到本地。
Retrofit retrofit =
new
Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//新的配置
.baseUrl(BASE_URL) .build(); MyService service = retrofit.create(MyService.class); service.login(phone, password)
//获取Observable对象
.subscribeOn(Schedulers.newThread())
//请求在新的线程中执行
.observeOn(Schedulers.io())
//请求完成后在io线程中执行
.doOnNext(
new
Action1<UserInfo>() { @Override
public
void
call
(UserInfo userInfo) { saveUserInfo(userInfo);
//保存用户信息到本地
} }) .observeOn(AndroidSchedulers.mainThread())
//最后在主线程中执行
.subscribe(
new
Subscriber<UserInfo>() { @Override
public
void
onCompleted
() { } @Override
public
void
onError
(Throwable e) {
//请求失败
} @Override
public
void
onNext
(UserInfo userInfo) {
//请求成功
} });
RxJava + Retrofit 形式的时候,Retrofit 把请求封装进 Observable ,在请求结束后调用 onNext() 或在请求失败后调用 onError()。
可以看到,调用了service的login方法后得到Observable对象,在新的线程中执行网络请求,请求成功后切换到io线程执行保存用户信息的动作,最后再切换到主线程执行请求失败onError()、请求成功onNext()。整体的逻辑十分清晰都在一条链中,就算还有别的要求还可以往里面添加,丝毫不影响代码的简洁。(终于举了一个有实际意义的例子)
RxJava + Retrofit 进阶
在上面举到登录后保存用户信息的例子,其实在做项目的时候,往往在登录后得到的并不是用户信息。一般登录后会得到token,然后根据token去获取用户的信息。他们的步骤是这样的:
1、登录
2、获取用户信息(前提:登录成功)
可以看得出来,这是一个嵌套的结构...嵌套啊!!!天呐,最怕嵌套的结构了。
//登录,获取token
@GET(
"/login"
)
public
Observable<String>
login
( @Query(
"username"
) String username, @
Query
(
"password"
) String password);
//根据token获取用户信息
@GET(
"/user"
)
public
Observable<User>
getUser
( @Query(
"token"
) String token);
//..................................
service.login(
"11111"
,
"22222"
) .flatMap(
new
Func1<String, Observable<User>>() {
//得到token后获取用户信息
@Override
public
Observable<User>
onNext
(String token) {
return
service.getUser(token); }) .subscribeOn(Schedulers.newThread())
//请求在新的线程中执行请求
.observeOn(Schedulers.io())
//请求完成后在io线程中执行
.doOnNext(
new
Action1<User>() {
//保存用户信息到本地
@Override
public
void
call
(User userInfo) { saveUserInfo(userInfo); } }) .observeOn(AndroidSchedulers.mainThread())
//在主线程中执行
.subscribe(
new
Observer<User>() { @Override
public
void
onNext
(User user) {
//完成一次完整的登录请求
userView.setUser(user); } @Override
public
void
onCompleted
() { } @Override
public
void
onError
(Throwable error) {
//请求失败
} });
通过一个flatMap()轻松完成一次嵌套的请求,而且逻辑十分清晰。so easy~~~
这篇文章也是补充的,比较经典
【Android】RxJava的使用(三)转换——map、flatMap
可以看到Observable中原来的参数是Student对象,而最后我们需要的是name,
这里使用了map来实现这一转换的过程。当然,map可以多次使用
。
值得注意的地方
文字叙述总归难理解,上代码:
Observable.just(
1
,
2
,
3
,
4
)
.subscribeOn(Schedulers.io())
//
指定
subscribe()
发生在
IO
线程
.observeOn(AndroidSchedulers.mainThread())
//
指定
Subscriber
的回调发生在主线程
.subscribe(
new
Action1<Integer>() {
@Override
public void
call(Integer
number
) {
Log.
d
(tag,
"number:"
+
number
);
}
});
上面这段代码中,由于
subscribeOn(Schedulers.io())
的指定,
被创建的事件
的内容
1
、
2
、
3
、
4
将会在 IO 线程发出
;而由于
observeOn(AndroidScheculers.mainThread()
) 的指定,因此
subscriber
数字的
打印将发生在主线程
。事实上,这种在
subscribe()
之前写上两句
subscribeOn(Scheduler.io())
和
observeOn(AndroidSchedulers.mainThread())
的使用方式非常常见,它适用于多数的 『后台线程取数据,主线程显示』的程序策略。
非常的重要
Observable 即被观察者 中的just用法
- 被观察者
Observable 即被观察者,它决定什么时候触发事件以及触发怎样的事件。可以使用create()、just(T...)、from(T[])或from(Iterable<? extends T>)来创建一个 Observable ,并为它定义事件触发规则。
- 订阅
创建了Observable和Observer之后,再用subscribe()方法将它们联结起来
参数说明
rxjava的学习
这里仅仅是帮助你了解RxJava,整个系列共有四篇文章,希望你看完这四篇文章之后能够了解RxJava背后的思想,并且喜欢上RxJava。
基础
RxJava最核心的两个东西是Observables(被观察者,事件源)和Subscribers(观察者)。Observables发出一系列事件,Subscribers处理这些事件。这里的事件可以是任何你感兴趣的东西(触摸事件,web接口调用返回的数据。。。)
一个Observable可以发出零个或者多个事件,知道结束或者出错。每发出一个事件,就会调用它的Subscriber的onNext方法,最后调用Subscriber.onNext()或者Subscriber.onError()结束。
Rxjava的看起来很想设计模式中的观察者模式,但是有一点明显不同,那就是如果一个Observerble没有任何的的Subscriber,那么这个Observable是不会发出任何事件的。
Hello World
创建一个Observable对象很简单,直接调用Observable.create即可
rxjava 基础知识
这个比较详细
Lambda
在 Steve Yegge 辛辣又幽默的
博客文章
里,描绘了 Java 世界是如何严格地以名词为中心的,如果你还没看过,赶紧去读吧,写得非常风趣幽默,而且恰如其分地解释了为什么 Java 要引进 Lambda 表达式。
Lambda 表达式为 Java 添加了缺失的函数式编程特点,使我们能将函数当做一等公民看待。尽管不完全正确,我们很快就会见识到 Lambda 与闭包的不同之处,但是又无限地接近闭包。在支持一类函数的语言中,Lambda 表达式的类型将是函数。但是,在 Java 中,Lambda 表达式是对象,他们必须依附于一类特别的对象类型——函数式接口(functional interface)。我们会在后文详细介绍函数式接口。
Lambda 表达式简介
Lambda 表达式是一种匿名函数(对 Java 而言这并不完全正确,但现在姑且这么认为),简单地说,它是没有声明的方法,也即没有访问修饰符、返回值声明和名字。
你可以将其想做一种速记,在你需要使用某个方法的地方写上它。当某个方法只使用一次,而且定义很简短,使用这种速记替代之尤其有效,这样,你就不必在类中费力写声明与方法了。