美文网首页Android 学习资源Android进阶之光Android学习
Android网络编程(九)Retrofit2前篇[基本使用]

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

作者: 刘望舒 | 来源:发表于2016-09-11 17:42 被阅读1246次

    相关文章
    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前篇[基本使用]

        本文链接:https://www.haomeiwen.com/subject/ltryettx.html