Retrofit2.0使用详解

1.概述

Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端,网络服务基于OkHttp 。修复了一些老版本的bug
Retrofit项目Github主页:https://github.com/square/retrofit
Retrofit项目官方文档:http://square.github.io/retrofit/

2.设置

1)权限:首先确保在AndroidManifest.xml中请求了网络权限 :

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

2)Android Studio用户,在app/build.gradle文件中添加如下代码:
Retrofit依赖于okhttp,所以需要集成OkHttp
如果接收JSON 结果并解析成POJO,必须把Gson Converter 作为一个独立的依赖添加进来。

dependencies {
    compile 'com.squareup.retrofit2:retrofit:2.0.1'
compile 'com.squareup.okhttp3:okhttp:3.2.0'

    compile 'com.google.code.gson:gson:2.6.2'
    compile 'com.squareup.retrofit2:converter-gson:2.0.1'
}

或者点这里下载相关jar包http://download.csdn.net/detail/leihuiaa/9661312
Square提供的官方Converter modules列表。选择一个最满足你需求的。

Gson: com.squareup.retrofit:converter-gson
Jackson: com.squareup.retrofit:converter-jackson
Moshi: com.squareup.retrofit:converter-moshi
Protobuf: com.squareup.retrofit:converter-protobuf
Wire: com.squareup.retrofit:converter-wire
Simple XML: com.squareup.retrofit:converter-simplexml

3.从资源中创建Java对象

Web API返回的数据为JSON或者XML格式,一旦数据从Web下载完成,即将其解析成普通Java类(POJO)。要把JSON解析成数据对象,需要响应的Java对象,因此我们需要先自己构造Java对象。
3.1手动创建
建议你使用手动的方式,因为这样你能更好的理解自动生成代码是如何工作的。
3.2自动生成
使用Android Studio插件GsonFormat生成POJO,创建一个POJO类PhoneResult.java
Retrofit2.0使用详解_第1张图片

4.创建Retrofit实例

要向一个Web API发送我们的网络请求 ,我们需要使用 Retrofit builder 类并指定service的base URL (通常情况下就是域名)。

public static final String BASE_URL = "http://api.myservice.com";
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).build();

4.1Gson library

public static final String BASE_URL = "http://api.myservice.com";
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
    .addConverterFactory(GsonConverterFactory.create())
    .build();

4.2添加多个converters

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(ProtoConverterFactory.create())
    .build();

5.定义Endpoints

在Retrofit 2中,Endpoints是定义在一个interface里面的,使用特殊的retrofit 注解来映射参数以及请求方法这些细节。另外,返回值始终是一个参数化了的Call对象,比如Call。如果你不需要任何类型安全的响应,你可以把返回值指定为Call。
5.1Request Method
Retrofit提供了5种内置的注解:GET、POST、PUT、DELETE和HEAD,在注解中指定的资源的相对URL

@GET("users/list")
//也可以在URL中指定查询参数
@GET("users/list?sort=desc")  //固定查询参数

5.2URL ManIpulation
请求的URL可以在函数中使用替换块和参数进行动态更新,替换块是{ and }包围的字母数字组成的字符串,相应的参数必须使用相同的字符串被@Path进行注释

@GET("group/{id}/users")
Call> groupList(@Path("id") int groupId);

也可以添加查询参数

@GET("group/{id}/users")
Call> groupList(@Path("id") int groupId, 
@Query("sort") String sort);

复杂的查询参数可以使用Map进行组合

@GET("group/{id}/users")
Call<List> groupList(@Path("id") int groupId, 
@QueryMap Map<String, String> options);

5.3Request Body
可以通过@Body注解指定一个对象作为Http请求的请求体

@POST("users/new")
Call<User> createUser(@Body User user);

5.4Header ManIpulation
固定头

interface SomeService {
 @GET("/some/endpoint")
 @Headers("Accept-Encoding: application/json")
 Call someEndpoint();
}

动态头

interface SomeService {
 @GET("/some/endpoint")
 Call someEndpoint(
 @Header("Location") String location);
}

someService.someEndpoint("Droidcon NYC 2015");
// GET /some/endpoint HTTP/1.1
// Location: Droidcon NYC 2015

固定+动态头

interface SomeService {
 @GET("/some/endpoint")
 @Headers("Accept-Encoding: application/json")
 Call someEndpoint(
 @Header("Location") String location);
}

someService.someEndpoint("Droidcon NYC 2015");

// GET /some/endpoint HTTP/1.1
// Accept-Encoding: application/json

6.调用百度API手机号归属地接口查询的Demo

Retrofit2.0使用详解_第2张图片
接口的API主机地址为:http://apis.baidu.com
资源地址为:/apistore/mobilenumber/mobilenumber
6.1Web API
们需要构造一个GET请求,添加一个Header,添加一个Query关键字,访问该API返回的数据格式如下:

{
    "errNum": 0,
    "retMsg": "success",
    "retData": {
        "phone": "15210011578",
        "prefix": "1521001",
        "supplier": "移动",
        "province": "北京",
        "city": "北京",
        "suit": "152卡"
    }
}

6.2创建返回结果POJO
根据返回结果我们创建数据对象PhoneResult, AndroidStudio插件 GsonFormat可以很方便地将Json数据转为Java对象.

public class PhoneResult {
    /**
     * errNum : 0
     * retMsg : success
     * retData : {"phone":"15210011578","prefix":"1521001","supplier":"移动","province":"北京","city":"北京","suit":"152卡"}
     */
    private int errNum;
    private String retMsg;
    /**
     * phone : 15210011578
     * prefix : 1521001
     * supplier : 移动
     * province : 北京
     * city : 北京
     * suit : 152卡
     */
    private RetDataEntity retData;

    public void setErrNum(int errNum) {
        this.errNum = errNum;
    }

    public void setRetMsg(String retMsg) {
        this.retMsg = retMsg;
    }

    public void setRetData(RetDataEntity retData) {
        this.retData = retData;
    }

    public int getErrNum() {
        return errNum;
    }

    public String getRetMsg() {
        return retMsg;
    }

    public RetDataEntity getRetData() {
        return retData;
    }

    public static class RetDataEntity {
        private String phone;
        private String prefix;
        private String supplier;
        private String province;
        private String city;
        private String suit;

        public void setPhone(String phone) {
            this.phone = phone;
        }

        public void setPrefix(String prefix) {
            this.prefix = prefix;
        }

        public void setSupplier(String supplier) {
            this.supplier = supplier;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public void setCity(String city) {
            this.city = city;
        }

        public void setSuit(String suit) {
            this.suit = suit;
        }

        public String getPhone() {
            return phone;
        }

        public String getPrefix() {
            return prefix;
        }

        public String getSupplier() {
            return supplier;
        }

        public String getProvince() {
            return province;
        }

        public String getCity() {
            return city;
        }

        public String getSuit() {
            return suit;
        }
    }
}

6.3创建Service接口

public interface PhoneService {
    @GET("/apistore/mobilenumber/mobilenumber")
Call getResult(
@Header("apikey") String apikey, 
@Query("phone") String phone);
}

6.4创建Retrofit对象

public class PhoneModel {

    public static final String BASE_URL = "http://apis.baidu.com"; // HOST地址
    public static final String API_KEY = "8e13586b86e4b7f3758ba3bd6c9c9135";//开发者Key

    private PhoneService service;

    //获取PhoneApi实例
    public static PhoneModel getModel(){
        return PhoneHolder.phoneModel;
    }

    //内部类实现单例模式,延迟加载,线程安全(java中class加载时互斥的),也减少了内存消耗
    private static class PhoneHolder{
        private static PhoneModel phoneModel = new PhoneModel();//单例对象实例
    }

    private PhoneModel(){//private的构造函数用于避免外界直接使用new来实例化对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)
                //转换服务器数据到对象
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        service = retrofit.create(PhoneService.class);
    }

    //获取PhoneService实例
    public PhoneService getService(){
        return service;
    }

}

6.5发送请求

public class MainActivity extends AppCompatActivity {

    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        tv = (TextView)findViewById(R.id.tv);
    }

    public void queryPhone(View v){
        Call call = PhoneModel.getModel().getService().getResult(PhoneModel.API_KEY, "17771008203");

        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                if (response.isSuccessful()) {
                    PhoneResult result = response.body();
                    if (result != null && result.getErrNum() == 0) {
                        PhoneResult.RetDataBean entity = result.getRetData();
                        tv.append("地址:" + entity.getCity());
                    }
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {

            }
        });


    }
}

6.6运行结果
Retrofit2.0使用详解_第3张图片

总结

好了Retrofit2.0只能讲到这里了,多敲敲多练练就会了。或者点击这里免费下载源码https://github.com/1234567leihui/Retrofit

你可能感兴趣的:(Retrofit2.0使用详解)