神刀安全网

Android网络编程(九)Retrofit2前篇[基本使用]

相关文章
Android网络编程(一)HTTP协议原理
Android网络编程(二)HttpClient与HttpURLConnection
Android网络编程(三)Volley用法全解析
Android网络编程(四)从源码解析volley
Android网络编程(五)OkHttp2.x用法全解析
Android网络编程(六)OkHttp3用法全解析
Android网络编程(七)源码解析OkHttp前篇[请求网络]
Android网络编程(八)源码解析OkHttp后篇[复用连接池]

前言

Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,而OkHttp现在已经得到Google官方认可,不了解OKHttp的请查看本系列的前作。

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依赖包 }

当然别忘了在manifest加入访问网络的权限:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

这次我们访问的网站产生了变化,我们用淘宝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异步访问网络

编写实体类

我们可以用JSON字符串转换成Java实体类(POJO)这个网站将Json转为实体类,经过修改的实体类如下:

IpModel.java:

public class IpModel {     private int code;     private IpData data;     public void setCode(int code) {         this.code = code;     }     public int getCode() {         return this.code;     }     public void setData(IpData data) {         this.data = data;     }     public IpData getData() {         return this.data;     } }

IpData.java:

public class IpData {     private String country;     private String country_id;     private String area;     private String area_id;     private String region;     private String region_id;     private String city;     private String city_id;     private String county;     private String county_id;     private String isp;     private String isp_id;     private String ip;     public void setCountry(String country) {         this.country = country;     }     public String getCountry() {         return this.country;     }     public void setCountry_id(String country_id) {         this.country_id = country_id;     }     ...  }

请求网络接口

public interface IpService{     @GET("getIpInfo.php")     Call<IpModel> getIpMsg(@Query("ip")String ip); }

Retrofit提供的请求方式注解有@GET和@POST等,分别代表GET请求和POST请求,我们在这里访问的界面是“getIpInfo.php”。参数注解有@PATH和@Query等,@Query就是我们的请求的键值对的设置,在这里@Query(“ip”)代表键,“String ip”则代表值。

创建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类型。

用Retrofit创建接口文件

 IpService ipService = retrofit.create(IpService.class);  Call<IpModel>call=ipService.getIpMsg(ip);

用retrofit创建我们之前定义的IpService接口对象,并调用该接口定义的getIpMsg方法得到Call对象。

用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()。

完整的代码如下:

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.请求参数

上文讲了Retrofit访问网络的基本方法,接下来我们来了解下Retrofit常用的请求参数。

请求方法

请求方法除了上文讲到的@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); }

github源码下载

参考资料
Retrofit 2.0文件上传
RxJava 与 Retrofit 结合的最佳实践
Retrofit2使用初探
android 介绍Retrofit的简单使用
Retrofit框架使用笔记
Retrofit 解析 JSON 数据
用 Retrofit 2 简化 HTTP 请求
Android Retrofit 2.0使用

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Android网络编程(九)Retrofit2前篇[基本使用]

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址