转载 http://www.jianshu.com/p/85bc4c5fe06c
说了这么多功能,我们来看看为什么要使用OkGo这个框架。
首先目前主流的几个网络框架
在此引用知乎上Stay Zhang的回答:
我们来先说一个常识性的错误:volley, retrofit, android-async-http 帮你封装了具体的请求,线程切换以及数据转换。而OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。
所以不要混淆。
-----以下纯个人主观见解
首先,我想即使你单纯使用OkHttp,还是会再包一层的,这样就等价于Volley之流的框架,只是封装的好与坏而已。
android-async-http内部实现是基于HttpClient, 想必你肯定知道6.0之后HttpClient是不是系统自带的了,不过它在最近的更新中将HttpClient的所有代码copy了一份进来,所以还能使用。
Volley是官方出的,volley在设计的时候是将具体的请求客户端做了下封装:HurlStack,也就是说可以支持HttpUrlConnection, HttpClient, OkHttp,相当于模版模式吧,这样解耦还是非常方便的,可以随意切换,如果你之前使用过Volley,并习惯使用,那直接写个OkHttp扩展就行了。
Retrofit因为也是square出的,所以大家可能对它更崇拜些。Retrofit的跟Volley是一个套路,但解耦的更彻底:比方说通过注解来配置请求参数,通过工厂来生成CallAdapter,Converter,你可以使用不同的请求适配器(CallAdapter), 比方说RxJava,Java8, Guava。你可以使用不同的反序列化工具(Converter),比方说json, protobuff, xml, moshi等等。然而目前OkGo已经完全可以替代Retrofit,同样支持RxJava,但具有更强的灵活性和易用性。
所以就说这么多啦,选最适合项目的,选大多数人选择的,选简单易用的,选择使用流行技术的,就这么个标准,而OkGo正是在这种情况下诞生啦!!
目前使用的RxJava
版本如下
compile 'io.reactivex:rxjava:1.2.0'
compile 'io.reactivex:rxandroid:1.2.1'
OkRx
是 OkGo
的扩展,所以要想使用OkRx
,那么请先按照OkGo
的配置文档,做相应的初始化。
compile 'com.lzy.net:okrx:0.1.0' //Rx扩展
或者
compile 'com.lzy.net:okrx:+' //使用+,引用最新版
我们还是像正常使用OkGo的方式一样,传入我们需要请求的Url,和我们需要的参数,那么最关键的一行就是最后调用getCall()
这个方法。
这里传入的两个参数进行一下说明:
Convert
对象,表示需要将服务器返回的数据流解析成什么对象,这里我们先用最简单的String
做转换,StringConvert
对象也是库中内置的转换器。第二个参数是Adapter
对象,表示需要将解析的结果用什么对象包装,该参数可以省略不写,那么默认是Call
这个对象包装,当然,我们要使用Rx的调用,使用这个肯定是不行的,所以我们传入OkRx扩展的RxAdapter
对象,他是使用的Observable
对象包装的,同样他需要一个泛型,该泛型必须和Convert
的泛型一致,否则就发生了类型转换异常。
以上两个参数具体的注意事项我们后续详细再说。
Observable call = OkGo.post(Urls.URL_METHOD)//
.headers("aaa", "111")//
.params("bbb", "222")//
.getCall(StringConvert.create(), RxAdapter.create());
现在我们已经获取了Observable
对象了,熟悉RxJava
的你难道还不会使用了吗,以下是简单的在请求前弹出loading,结束后展示信息的代码。
call.doOnSubscribe(new Action0() {
@Override
public void call() {
showLoading(); //开始请求前显示对话框
}
})//
.observeOn(AndroidSchedulers.mainThread())//切换到主线程
.subscribe(new Action1() {
@Override
public void call(String s) {
dismissLoading(); //请求成功,关闭对话框
handleResponse(s, null, null);
}
}, new Action1() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
dismissLoading(); //请求失败
showToast("请求失败");
handleError(null, null);
}
});
上面的调用是不是很简单,有人可能觉得链试代码太长,没关系,我们完全可以像Retrofit一样,自己写一个ServerApi
类,这里面管理了所有的接口请求和参数,只是OkGo并不是采用的注解和反射实现的,而是通过传参来实现,相信对你你来讲,这样的方式更加直观。我们再将调用配合上lambda
表达式,那么最后的结果是这样的:
这样的请求方式有没有惊艳到你!!
OkGo.post(Urls.URL_METHOD)//
.headers("aaa", "111")//
.params("bbb", "222")//
.getCall(StringConvert.create(), RxAdapter.create())//以上为产生请求事件,请求默认发生在IO线程
.doOnSubscribe(() -> {
showLoading(); //开始请求前显示对话框
})
.observeOn(AndroidSchedulers.mainThread())//切换到主线程
.subscribe(s -> {
dismissLoading(); //请求成功,关闭对话框
handleResponse(s, null, null);
}, throwable -> {
throwable.printStackTrace();
dismissLoading(); //请求失败
showToast("请求失败");
handleError(null, null);
});
String
,那么将第2
步中的getCall
方法,就是你想要的。 getCall(StringConvert.create(), RxAdapter.create())
Bitmap
,那么将第2
步中的getCall
方法,改成如下形式 getCall(BitmapConvert.create(), RxAdapter.create())
File
,那么还是修改这行 getCall(new FileConvert(), RxAdapter.create())
Json
对象,聪明的你一定知道还是这行。注意看Convert最后有个大括号,千万不能忘记
getCall(new JsonConvert() {}, RxAdapter.create())
List
对象,也很简单。注意看Convert最后有个大括号,千万不能忘记
getCall(new JsonConvert>() {}, RxAdapter.>create())
我想,对于一款普通的app,这些请求一定能满足你90%以上的需求,而且使用方便,只需要改一行代码,就能直接获取到你想要的数据。
推荐对每一个网络请求的Subscription
对象都交由统一的CompositeSubscription
去管理,在界面销毁或者需要取消的地方调用。
例如:在Activity中,当Activity销毁取消请求,可以在onDestory里面统一取消。
@Override
protected void onDestroy() {
super.onDestroy();
unSubscribe();
}
目前内部提供的包含Converter
, StringConvert
,BitmapConvert
,FileConvert
,可以根据自己的需求去自定义Convert
Converter
: 接口,所有转换器必须实现StringConvert
:将网络结果解析转成String
BitmapConvert
:将网络结果解析转成Bitmap
FileConvert
:将网络结果解析转成File
JsonConvert
,由于不同的业务实现都不一样,所以并不放在库中,提供参考实现供自己修改