Android Retrofit 2.0使用
实例带你了解Retrofit 2.0的使用,分享目前开发Retrofit遇到的坑和心得。
添加依赖
app/build.gradle
|
1
|
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta3'
|
接口调用
|
1
2
3
4
5
6
|
Retrofit retrofit = new Retrofit.Builder()
//这里建议:- Base URL: 总是以/结尾;- @Url: 不要以/开头
.baseUrl("http://www.weather.com.cn/")
.build();
ApiStores apiStores = retrofit.create(ApiStores.class);
Call<ResponseBody> call = apiStores.getWeather("101010100");
|
如果@GET(“http://ip.taobao.com/service/getIpInfo.php"),则baseUrl无效。
注意这个任务是网络任务,不要忘记给程序加入网络权限
|
1
|
<uses-permission android:name="android.permission.INTERNET" />
|
同步调用
|
1
2
3
4
5
6
7
|
try {
Response<ResponseBody> bodyResponse = call.execute();
String body = bodyResponse.body().string();//获取返回体的字符串
Log.i("wxl", "body=" + body);
} catch (IOException e) {
e.printStackTrace();
}
|
同步需要处理android.os.NetworkOnMainThreadException
异步调用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response) {
try {
Log.i("wxl", "response=" + response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFailure(Throwable t) {
Log.i("wxl", "onFailure=" + t.getMessage());
}
});
|
移除请求
|
1
|
call.cancel();
|
接口参数
Path
|
1
2
3
4
5
6
7
8
9
|
/**
* Call<T> get();必须是这种形式,这是2.0之后的新形式
* 如果不需要转换成Json数据,可以用了ResponseBody;
* 你也可以使用Call<GsonBean> get();这样的话,需要添加Gson转换器
*/
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
Call<ResponseBody> getWeather(@Path("cityId") String cityId);
}
|
Query
如果链接是http://ip.taobao.com/service/getIpInfo.php?ip=202.202.33.33
|
1
2
|
Call<ResponseBody> getWeather(@Query("ip") String ip);
|
Body
这是针对POST方式,如果参数是json格式,如:
|
1
2
3
4
5
6
|
{
"apiInfo": {
"apiName": "WuXiaolong",
"apiKey": "666"
}
}
|
建立Bean
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class ApiInfo {
private ApiInfoBean apiInfo;
public ApiInfoBean getApiInfo() {
return apiInfo;
}
public void setApiInfo(ApiInfoBean apiInfo) {
this.apiInfo = apiInfo;
}
public class ApiInfoBean {
private String apiName;
private String apiKey;
//省略get和set方法
}
}
|
代码调用
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
private void getCarType() {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://WuXiaolong.me/")
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiStores apiStores = mRetrofit.create(ApiStores.class);
ApiInfo apiInfo = new ApiInfo();
ApiInfo.ApiInfoBean apiInfoBean = apiInfo.new ApiInfoBean();
apiInfoBean.setApiKey("666");
apiInfoBean.setApiName("WuXiaolong");
apiInfo.setApiInfo(apiInfoBean);
Call<ResponseBody> call = apiStores.getCarType(apiInfo);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Response<ResponseBody> response) {
String body = null;//获取返回体的字符串
try {
body = response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
Log.i("wxl", "get=" + body);
}
@Override
public void onFailure( Throwable t) {
}
});
}
|
ApiStores
|
1
2
3
4
|
public interface ApiStores {
@POST("client/shipper/getCarType")
Call<ResponseBody> getCarType(@Body ApiInfo apiInfo);
}
|
JSON解析库
Retrofit 2现在支持许多种解析方式来解析响应数据,包括Moshi,一个由Square创建的高效JSON解析库。
添加gson依赖
app/build.gradle
|
1
|
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
|
jsonschema2pojo
访问jsonschema2pojo,自动生成Java对象,如果你对gson还不熟悉,笔者建议你手动生成Java对象,感受下。
这里如果选择Gson,生成的代码中存在@Generated注解,Android默认并没有javax.annotation library。如果你希望保留@Generated注解,需要添加如下的依赖。
|
1
|
compile 'org.glassfish:javax.annotation:10.0-b28'
|
或者,你可以直接删除这个注解,完全没有问题。笔者当然不会加这个依赖啦。
Gsonformat
作用:Android studio插件,一般接口返回数据后要建立自己的bean,Gsonformat帮助你快速生成,不用一条一条去写。比jsonschema2pojo更加简单。
安装步骤:Android studio-Settings-Plugins-搜Gsonformat-Install Plugin
效果预览:
实例代码
依旧演示上面的天气:http://www.weather.com.cn/adat/sk/101010100.html
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class WeatherJson {
//weatherinfo需要对应json数据的名称,我之前随便写了个,被坑很久
private Weatherinfo weatherinfo;
public Weatherinfo getWeatherinfo() {
return weatherinfo;
}
public void setWeatherinfo(Weatherinfo weatherinfo) {
this.weatherinfo = weatherinfo;
}
//city、cityid必须对应json数据的名称,不然解析不了
public class Weatherinfo {
private String city;
private String cityid;
private String temp;
private String WD;
private String WS;
private String SD;
private String WSE;
private String time;
private String isRadar;
private String Radar;
private String njd;
private String qy;
//这里省略get和set方法
}
}
|
ApiStores:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public class AppClient {
static Retrofit mRetrofit;
public static Retrofit retrofit() {
if (mRetrofit == null) {
mRetrofit = new Retrofit.Builder()
.baseUrl("http://www.weather.com.cn/")
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return mRetrofit;
}
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
Call<WeatherJson> getWeather(@Path("cityId") String cityId);
}
}
|
调用:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
private void getWeather() {
AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
Call<WeatherJson> call = apiStores.getWeather("101010100");
call.enqueue(new Callback<WeatherJson>() {
@Override
public void onResponse(Response<WeatherJson> response) {
Log.i("wxl", "getWeatherinfo=" + response.body().getWeatherinfo().getCity());
}
@Override
public void onFailure(Throwable t) {
}
});
}
|
经Gson转换器,Call<ResponseBody>换成自己要写的Call<WeatherJson>
RxJava
依赖以下:
|
1
2
|
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta3'
compile 'io.reactivex:rxandroid:1.0.1'
|
增加addCallAdapterFactory
|
1
2
3
4
5
|
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.nuuneoi.com/base/")
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
|
ApiStores
|
1
2
|
@GET("adat/sk/{cityId}.html")
Observable<WeatherJson> getWeatherRxjava(@Path("cityId") String cityId);
|
subscribe部分的代码在Schedulers.io被调用,需要把observeOn(AndroidSchedulers.mainThread())添加到链表中。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
private void getWeatherRxjava() {
AppClient.ApiStores apiStores = AppClient.retrofit().create(AppClient.ApiStores.class);
Observable<WeatherJson> observable = apiStores.getWeatherRxjava("101010100");
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<WeatherJson>() {
@Override
public void onCompleted() {
Log.i("wxl", "onCompleted");
}
@Override
public void onError(Throwable e) {
Log.i("wxl", "e=" + e.getMessage());
}
@Override
public void onNext(WeatherJson weatherJson) {
Log.i("wxl", "getWeatherinfo=" + weatherJson.getWeatherinfo().getCity());
}
});
}
|
Retrofit源码解析
另见白瓦力的博客,分析的很到位,解释了0、Retrofit 是什么,1、Retrofit 怎么用,2、Retrofit的原理是什么,3、一些总结。
博客地址:http://bxbxbai.github.io/2015/12/13/retrofit2/
PS:十分感谢白瓦力,他教会我们如何去查看源码的一种有效方法,debug一步步去跟源码。
Android Retrofit 2.0使用的更多相关文章
- Android Retrofit 2.0 使用-补充篇
推荐阅读,猛戳: 1.Android MVP 实例 2.Android Retrofit 2.0使用 3.RxJava 4.RxBus 5.Android MVP+Retrofit+RxJava实践小 ...
- android -------- Retrofit + RxJava2.0 + Kotlin + MVP 开发的 WanAndroid 项目
简介 wanandroid项目基于 Retrofit + RxJava2.0 + Kotlin + MVP 用到的依赖 implementation 'io.reactivex.rxjava2:rxj ...
- Android Retrofit 2.0文件上传
Android Retrofit 实现(图文上传)文字(参数)和多张图片一起上传 使用Retrofit进行文件上传,肯定离不开Part & PartMap. public interface ...
- Android - Retrofit 2.0 使用教程(含实例讲解)
链接:https://blog.csdn.net/carson_ho/article/details/73732076
- Android:手把手带你深入剖析 Retrofit 2.0 源码
前言 在Andrroid开发中,网络请求十分常用 而在Android网络请求库中,Retrofit是当下最热的一个网络请求库 今天,我将手把手带你深入剖析Retrofit v2.0的源码,希望你们会喜 ...
- Retrofit 2.0 超能实践(四),完成大文件断点下载
作者:码小白 文/CSDN 博客 本文出自:http://blog.csdn.net/sk719887916/article/details/51988507 码小白 通过前几篇系统的介绍和综合运用, ...
- Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
文:http://blog.csdn.net/sk719887916/article/details/51755427 Tamic 简书&csdn同步 通过前两篇姿势的入门 Retrofit ...
- Retrofit 2.0 超能实践(一),okHttp完美支持Https传输
http: //blog.csdn.net/sk719887916/article/details/51597816 Tamic首发 前阵子看到圈子里Retrofit 2.0,RxJava(Andro ...
- Retrofit 2.0 超能实践,完美支持Https传输
http://blog.csdn.NET/sk719887916/article/details/51597816 前阵子看到圈子里Retrofit 2.0,RxJava(Android), OkHt ...
随机推荐
- day27 封装
广义上的面向对象的封装: 代码的保护,面向对象思想本身就是一种封装 只让自己的对象调用自己类的方法 狭义的封装: 面向对象的三大特性之一,其他两个是继承和多态. 属性和方法都可以藏起来不让你看到 cl ...
- OpenAI 开源机器人模拟 Python 库,并行模拟处理速度提升400%
10000da.cnvboyule.cnjiaeidaypt.cn 在过去一年的研究中,OpenAI团队开源一个使用 MuJoCoengine开发的用于机器人模拟的高性能Python库.雷锋网了解到 ...
- Leetcode 283.移动零 By Python
思路 我们可以用python的list comprehension来取出所以非0的元素,而且这样取出来会保持原有的相对顺序,再统计先后变化的长度,补上相应的0即可 代码 class Solution( ...
- 【BZOJ1856】[SCOI2010]字符串(组合数学)
[BZOJ1856][SCOI2010]字符串(组合数学) 题面 BZOJ 洛谷 题解 把放一个\(1\)看做在平面直角坐标系上沿着\(x\)正半轴走一步,放一个\(0\)看做往\(y\)轴正半轴走一 ...
- 【BZOJ1880】[Sdoi2009]Elaxia的路线(最短路)
[BZOJ1880][Sdoi2009]Elaxia的路线(最短路) 题面 BZOJ 洛谷 题解 假装我们知道了任意两点间的最短路,那么我们怎么求解答案呢? 不难发现公共路径一定是一段连续的路径(如果 ...
- 用DotNetOpenAuth实现基于OAuth 2.0的web api授权 (一)Getting Start
1. 下载 源码下载 2. build solution,创建虚拟目录: 右健MyContatacts/MyPromo项目,选择Properties,点击左边的Web,点击 Create Virtua ...
- jsp关闭或刷新浏览器(解决浏览器不兼容),请求后台onbeforeunload、onunload
jsp关闭或刷新浏览器(解决浏览器不兼容),请求后台 onbeforeunload.onunload 1.看代码: function test(e) { var json = "退出,清理 ...
- java 中自定义类的概述
作业: 描述商品类 Goods 4个属性 商品名字 大小 价格 库存 把商品类放进集合中 小米品牌 大小 价格 库存的数量 都存集合 华为..... 魅族 public class Goods{ St ...
- 4、Python-列表
列表格式 # 元素可以是不同类型的 namesList = [1, 'xiaoZhang', 'xiaoHua'] print(namesList[0]) print(namesList[1]) pr ...
- VirtualBox设置共享文件夹
前提是已经正确安装增强工具,在安装增强工具时,没有faile的,全部done 1.添加共享文件夹(已经在lmg下创建过目录 /mnt/bdshare ) sudo mount -t vboxsf Ba ...