新司机上路,如有错误,恳请各位热心指出错,大恩先言谢。
基于:
http://www.open-open.com/lib/view/open1453552147323.html
http://blog.youkuaiyun.com/wbwjx/article/details/51379506
需求
我就想用Retrofit从淘宝提供的Ip查询Api查下我的地方嘛
解读
首先Retrofit是用主要拿来访问网络的嘛 所以 我先从网络地址入手
需要访问一个API:
http://ip.taobao.com/service/getIpInfo.php?ip=202.202.32.202
首先把网址切开:
baseUrl = http://ip.taobao.com/
剩下的再切:
“service/getIpInfo.php”+ “?ip=202.202.32.202”
上面后部分的“?”后面的估计是http的Query了。如果我想在我代码不仅查ip=202.202.32.202还想查ip=其他的,该怎么办呢?
(我好奇为什么要切呢?是不是动态代理的意思呢?)
所以使用步骤简单为三部曲:Retrofit—接口—合体:
- 基于上面切出来的baseUrl( “= http://ip.taobao.com/”)生成一个Retrofit;(那我网址剩下的#¥%#不要了?不是的,丢给下面接口小弟让他自己折腾)
- 利用老大丢下来的(service/getIpInfo.php)提供一个接口Service让客户修改ip=(我想要查的);(接盘侠,废物利用,就是剩下的网址啦,提供修改接口。好爽的样子,不需要每一个IP都重写一个地址,)
- 把接口Service与Retrofit合体(变成能访问网络的接口了,它自己就会把网址拼接完整)
- 合体出的娃 跑去网络扒资料了。
使用步骤
.前戏:网络权限,gradle配置
1. 创建Retrofit实例(利用baseUrl)
public static final String BASE_URL = "http://ip.taobao.com/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())//自动把json 结果解析成DAO
.build();
- 创建接口(大家喜欢命名为service):
public interface TaobaoIpService{
@GET("service/getIpInfo.php")//把老大丢网址的捡回来
Call<IP> setIp(@Query("ip") String mIp);
//估计用@query 就是自动把网址补为?ip=mIp;
}
上面返回Call< IP>是什么鬼?个人理解是你设置IP后返回一个CALL接口。后面拿来执行访问网络的。
- 上述两者请合体
static public TaobaoIpService taobaoIpService=
retrofit.create(TaobaoIpService.class);
他们合体后还是接口Service 估计测接口让内部返回的call< IP>具有访问网络的功效了。
合体后:网址内部还差?ip=xxx其他应该也合体了吧。
这时候内部网址应该是:
http://ip.taobao.com/service/getIpInfo.php?ip=
- 合体的娃,自由的飞吧
Call<IP>call=RetrofitUtil.taobaoIpService.getIp("202.202.32.202");
//这时网址应该是完整的了:
//http://ip.taobao.com/service/getIpInfo.php?ip=202.202.32.202
自由飞翔(分同步,异步飞翔,同步不说了)
call.enqueue(new Callback<IP>() {
@Override
public void onResponse(Call<IP> call, final Response<IP> response) {
//ui线程执行
IP ip=response.body();
text.setText(ip.getCode());
}
@Override
public void onFailure(Call<IP> call, Throwable t) {
}
});
学习其他心得
注意:retrofit2.0后:BaseUrl要以/结尾;@GET 等请求不要以/开头;@Url: 可以定义完整url,不要以 / 开头。
1.遇到一个坑:
Retrofit是基于baseUrl建立的是吧?那是不是不同Api就得写不同的Retrofit了?不能单例模式了嘛?
答:你开玩笑把,你不造Retrofit可以把baseUrl都改了吗?
@Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景
@GET
Call<ResponseBody> v3(@Url String url);
2.retrofit是提供Gsonconverter的,可方便直接解析Json,但如果我就想要Json呢,如下处理:
->first:
接口service处,把setIp(*)返回的值 call< T >里面的类型改成(ResponseBody)
public interface TaobaoIpService{
@GET("service/getIpInfo.php")
Call<ResponseBody> setIp(@Query("ip") String mIp);
}
->second:
把合体的娃Call< T >也改ResponseBody:
Call<ResponseBody>call=RetrofitUtil.taobaoIpService.getIp("202.202.32.202");
->three:
然后在call异步调用回调onSucceed里面转换出来就是JsonObject了。
String jsonString=new String(response.body().bytes());
JsonParser parser=new JsonParser();//这里用的Gson;
JsonObject jsonObj=
parser.parse(jsonString).getAsJsonObject();
几个特殊的注解
http://blog.youkuaiyun.com/wbwjx/article/details/51379506
@HTTP:可以替代其他方法的任意一种
/**
* method 表示请的方法,不区分大小写
* path表示路径
* hasBody表示是否有请求体
*/
@HTTP(method = "get", path = "users/{user}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("user") String user);
@Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景
@GET
Call<ResponseBody> v3(@Url String url);
@Streaming:用于下载大文件
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();