1. 使用前准备
Step 1: 向配置build.gradle:
dependencies {
...
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:converter-scalars:2.1.0'//ConverterFactory的String依赖包
}
Step 2: 在MainFest中加入访问网络的权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Step 3: 查看淘宝IP地址库的接口说明
1. 请求接口(GET):
/service/getIpInfo.php?ip=[ip地址字串]
2. 响应信息:
(json格式的)国家 、省(自治区或直辖市)、市(县)、运营商
3. 返回数据格式:
{"code":0,"data":{"ip":"210.75.225.254","country":"\u4e2d\u56fd","area":"\u534e\u5317",
"region":"\u5317\u4eac\u5e02","city":"\u5317\u4eac\u5e02","county":"","isp":"\u7535\u4fe1",
"country_id":"86","area_id":"100000","region_id":"110000","city_id":"110000",
"county_id":"-1","isp_id":"100017"}}
其中code的值的含义为,0:成功,1:失败。
2.使用Retrofit异步访问网络
Step 1:编写实体类
利用 JSON字符串转换Java实体类 这个网站将JSON转换为实体类
public class JsonRootBean {
private int code;
private Data data;
public void setCode(int code) {
this.code = code;
}
public int getCode() {
return code;
}
public void setData(Data data) {
this.data = data;
}
public Data getData() {
return data;
}
}
public class Data {
private String ip;
private String country;
private String area;
private String region;
private String city;
private String county;
private String isp;
private String country_id;
private String area_id;
private String region_id;
private String city_id;
private String county_id;
private String isp_id;
public void setIp(String ip) {
this.ip = ip;
}
public String getIp() {
return ip;
}
public void setCountry(String country) {
this.country = country;
}
public String getCountry() {
return country;
}
public void setArea(String area) {
this.area = area;
}
public String getArea() {
return area;
}
public void setRegion(String region) {
this.region = region;
}
public String getRegion() {
return region;
}
public void setCity(String city) {
this.city = city;
}
public String getCity() {
return city;
}
public void setCounty(String county) {
this.county = county;
}
public String getCounty() {
return county;
}
public void setIsp(String isp) {
this.isp = isp;
}
public String getIsp() {
return isp;
}
public void setCountry_id(String country_id) {
this.country_id = country_id;
}
public String getCountry_id() {
return country_id;
}
public void setArea_id(String area_id) {
this.area_id = area_id;
}
public String getArea_id() {
return area_id;
}
public void setRegion_id(String region_id) {
this.region_id = region_id;
}
public String getRegion_id() {
return region_id;
}
public void setCity_id(String city_id) {
this.city_id = city_id;
}
public String getCity_id() {
return city_id;
}
public void setCounty_id(String county_id) {
this.county_id = county_id;
}
public String getCounty_id() {
return county_id;
}
public void setIsp_id(String isp_id) {
this.isp_id = isp_id;
}
public String getIsp_id() {
return isp_id;
}
}
Step 2:请求网络连接
Retrofit提供的请求方式注解有@GET和@POST等。
public interface IpService{
@GET("getIpInfo.php")
Call<JsonRootBean> getIpMsg(@Query("ip")String ip);
}
我们在这里访问的界面是“getIpInfo.php”。参数注解有@PATH和@Query等,@Query就是我们的请求的键值对的设置,在这里@Query(“ip”)代表键,“String ip”则代表值。
Step 3:创建Retrofit
String url = "http://ip.taobao.com/service/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
//增加返回值为String的支持
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
这里的baseUrl加上之前@GET(“getIpInfo.php”)定义的参数形成完整的请求地址;addConverterFactory用于指定返回的参数数据类型,这里我们支持String和Gson类型。
Step 4: 用Retrofit创建接口文件
IpService ipService = retrofit.create(IpService.class);
Call<IpModel>call=ipService.getIpMsg(ip);
用retrofit创建我们之前定义的IpService接口对象,并调用该接口定义的getIpMsg方法得到Call对象。
Step 5:用Call请求网络并处理回调
call.enqueue(new Callback<IpModel>() {
@Override
public void onResponse(Call<IpModel> call, Response<IpModel> response) {
String country= response.body().getData().getCountry();
Log.i("wangshu","country"+country);
Toast.makeText(getApplicationContext(),country,Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<IpModel> call, Throwable t) {
}
});
这里是异步请求网络,回调的Callback是运行在主线程的。得到返回的Response后将返回数据的country字段用Toast显示出来。如果想同步请求网络请使用 call.execute(),如果想中断网络请求则可以使用 call.cancel()。
Step Last:完整的代码:
public class MainActivity extends AppCompatActivity {
private Button bt_request;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_request = (Button) findViewById(R.id.bt_request);
bt_request.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getIpInformation("59.108.54.37");
}
});
}
private void getIpInformation(String ip) {
String url = "http://ip.taobao.com/service/";
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
//增加返回值为String的支持
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build();
IpService ipService = retrofit.create(IpService.class);
Call<IpModel>call=ipService.getIpMsg(ip);
call.enqueue(new Callback<IpModel>() {
@Override
public void onResponse(Call<IpModel> call, Response<IpModel> response) {
String country= response.body().getData().getCountry();
Log.i("wangshu","country"+country);
Toast.makeText(getApplicationContext(),country,Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<IpModel> call, Throwable t) {
}
});
}
3. 请求参数
请求方法除了上文讲到的@GET,还有@POST、@PUT、@DELETE、@HEAD、@OPTIONS、@PATCH、@HTTP。其中@HTTP用来替换以上7个,其他的分别对应着不同的请求方法,不明白的请查看Android网络编程(一)HTTP协议原理这一篇文章。
@Query
前面的例子就用了Query用来查询参数。
public interface IpService{
@GET("getIpInfo.php")
Call<IpModel> getIpMsg(@Query("ip")String ip);
}
@QueryMap
如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map统一传递。
public interface BlueService {
@GET("book/search")
Call<BookSearchResponse> getSearchBooks(@QueryMap Map<String, String> options);
}
@Path
@Path用来替换路径。
public interface ApiStores {
@GET("adat/sk/{cityId}.html")
Call<ResponseBody> getWeather(@Path("cityId") String cityId);
}
@Body
@Body与@POST注解一起使用,提供查询主体内容,其中ApiInfo是一个bean类。
public interface ApiStores {
@POST("client/shipper/getCarType")
Call<ResponseBody> getCarType(@Body ApiInfo apiInfo);
}
@Headers
interface SomeService {
@GET("some/endpoint")
@Headers("Accept-Encoding: application/json")
Call<ResponseBody> getCarType();
}
@Headers用来添加头部信息,上面用的是固定头部,也可以采用动态头部:
interface SomeService {
@GET("some/endpoint")
Call<SomeResponse> someEndpoint(
@Header("Location") String location);
}
@Multipart
@Multipart用来上传文件
public interface FileUploadService {
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
}