http://square.github.io/retrofit/ 框架的官方网站
Retrofit框架主要应用就是Http网络访问,基于okhttp做的封装,可以快速的完成请求数据,并将返回的数据解析成对象。
使用步骤:
1、创建一个接口
接口里封装了你的网络访问,包括请求方式,请求地址,请求参数,返回数据格式等。
例如:(我这个事例,利用了聚合数据提供的接口,聚合数据提供了很多很多有用的数据网络访问接口,想了解聚合数据的可以自己去查)
public interface IpService {
@GET("/ip/ip2addr")
Call<String> ipService(@Query("ip")String ip, @Query("key") String key);
}
@GET表明Http请求网络的方式,也可以写成POST
, PUT
, DELETE
GET后面括号里的当然是请求的相对地址,具体ip地址和端口好需要在使用Retrofit的地方进行配置
另外,如果请求中,需要添加头部请求,可以用@HEADS来标记
我这个请求用不上,大概写法是这样
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
如果Head中只有一个参数,这样写
@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();
这样写是固定的参数和内容,如果是动态的话,需要另写参数,下面会介绍。
Call<String>是网络请求之后返回的数据类型,我这里写的是String,如果返回的数据是Json或者XML等标准格式的话,
可以在这里直接写上解析完成的类的对象。比如返回是Json数据,可以是下面这个类
public class User {
/*
{
"name": "test",
"age": 18
}
*/
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
@Query是参数的名称及类型,括号里面的是参数名称,后面参数是类型,需要用户在调用这个接口的时候传递。
Query也可以写成Path,QueryMap,Header
写成Path表示你要访问的这个接口的地址,应该是需要动态补全,比如这个地址"users/{username}"
username就要用Path来写,例如 @Path("username") String name 这样写
QueryMap是把多个参数都添加到了某个map集合里,例如 @QueryMap Map<String, String> params 这样写
Header就是前面所说,当需要添加动态Header参数是,可以这样写,例如 @Header("header") String h
我这里只用到了Query,也就是参数的传递
写完这个接口,就可以开始使用Retrofit框架进行网络请求了,如果你用的不是String而是其他自定义类,你当然需要创建好你的类了。
2、构建Retrofit对象并访问接口
进行网络访问,当然得添加网络访问权限
<uses-permission android:name="android.permission.INTERNET"/>
Android不允许在主线程下访问网络,所以访问网络需要两外启动一个线程,如下:
new Thread(new Runnable() {
@Override
public void run() {
//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
//设置访问的IP地址及端口号
.baseUrl("http://apis.juhe.cn")
//设置返回数据要解析的数据类型
.addConverterFactory(ScalarsConverterFactory.create())
.build();
//获取网络访问接口的对象
IpService ipService = retrofit.create(IpService.class);
//设置对象的参数获取网络访问的对象,这个Call对象是真正进行网络访问的对象
Call<String> ipResultCall = ipService.ipService("www.baidu.com", "af3c4fc56461805251003c59c31ab150");
try {
//网络访问并获取数据,这行代码必须在非主线程下执行
Response<String> res = ipResultCall.execute();
int code = res.code();
if (code == 200) {
//获取网络访问返回的数据
String ipresult = res.body();
Message msg = handler.obtainMessage();
msg.obj = ipresult;
handler.sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
try {
//Call对象只能执行一次,如果想要继续执行,需要clone之后在execute
Response<String> res = ipResultCall.clone().execute();
String ipresult = res.body();
Message msg = handler.obtainMessage();
msg.what = 1;
msg.obj = ipresult;
handler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
在创建Retrofit对象时,设置addConverterFactory,可以有多种类型设置,前面是对应类型,后面是需要添加的库
- Gson:
com.squareup.retrofit2:converter-gson
- Jackson:
com.squareup.retrofit2:converter-jackson
- Moshi:
com.squareup.retrofit2:converter-moshi
- Protobuf:
com.squareup.retrofit2:converter-protobuf
- Wire:
com.squareup.retrofit2:converter-wire
- Simple XML:
com.squareup.retrofit2:converter-simplexml
- Scalars (primitives, boxed, and String):
com.squareup.retrofit2:converter-scalars
compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-scalars:2.1.0'
前一个是retrofit的库
我这个例子,返回的是json数据,可以添加Gson的库,直接将数据解析成对象
刚采访问网络调用的是excute方法,并获取返回的response数据
excute方法不会异步调用,所以我们需要自己启动线程。
Retrofit对象又一个异步调用的方法,就是enqueue
<span style="white-space:pre"> </span>//创建Retrofit对象
Retrofit retrofit = new Retrofit.Builder()
//设置访问的IP地址及端口号
.baseUrl("http://apis.juhe.cn")
//设置返回数据要解析的数据类型
.addConverterFactory(GsonConverterFactory.create())
.build();
//获取网络访问接口的对象
IpService ipService = retrofit.create(IpService.class);
//设置对象的参数获取网络访问的对象,这个Call对象是真正进行网络访问的对象
Call<IpResult> ipResultCall = ipService.ipServiceJson("www.baidu.com", "af3c4fc56461805251003c59c31ab150");
ipResultCall.enqueue(new Callback<IpResult>() {
@Override
public void onResponse(Call<IpResult> call, Response<IpResult> response) {
textView.setText(response.body().getResult().getArea() + " enqueue");
}
@Override
public void onFailure(Call<IpResult> call, Throwable t) {
}
});
enqueue方法会异步访问网络,并通过callback回调。
我这里设置了Json的解析,addConverterFactory(GsonConverterFactory.create())
所以会把服务器返回的json字符串数据直接解析为对象,给我使用。
事例项目下载地址:
http://download.csdn.net/detail/dengdaijc/9649581