Retrofit初探

之前了解到Retrofit这个网络框架是对okhttp的封装,就尝试用了下。

Retrofit的官网

直接根据官网介绍在build.gradle添加

implementation 'com.squareup.retrofit2:retrofit:*(insert latest version)*'

这里没有说什么版本的,进入GitHub看看吧。

GitHub - square/retrofit: Type-safe HTTP client for Android and Java by Square, Inc.

当前版本是2.5.0

下面就开始撸代码。

根据官方介绍,这里要吐槽一下官方的教程文档,简陋得不得再简陋。。只给出关键的方法,如果有些同学没有接触过okhttp估计有点懵逼。根据教程:

1. 定义请求接口:

public interface GetDomainService {

    @FormUrlEncoded
    @POST("/Domain.List")
    Call getDomain(@Field("login_token") String login_token, @Field("format") String format);
}

Retrofit的特点就是用注解,可能有同学说Android用注解效率低,其实现在的手机性能这么高,牺牲小小性能换来代码的优雅其实没有什么大不了的。

通过@GET, @POST, @PUT, @DELETE和@HEAD指定对应的请求方式,参数是请求路径。我这里用@POST,其他请求方式也是一样的。
@FormUrlEncoded:代表参数不用encode
@Field:代表地址参数的key,value就是你传进来的值。
当然还有很多其他注解,因为初探篇,暂不深入研究。

2.定义对应实体类:

public class DomainBean implements Serializable {

    public Status status;

    public Info info;

    public Domain[] domains;

    public class Status {
        public String code;
        public String message;
        public String created_at;

        @Override
        public String toString() {
            return "Status{" +
                    "code='" + code + '\'' +
                    ", message='" + message + '\'' +
                    ", created_at='" + created_at + '\'' +
                    '}';
        }
    }

    public class Info {
        public int domain_total;
        public int all_total;
        public int mine_total;
        public String share_total;
        public int vip_total;

        @Override
        public String toString() {
            return "Info{" +
                    "domain_total=" + domain_total +
                    ", all_total=" + all_total +
                    ", mine_total=" + mine_total +
                    ", share_total='" + share_total + '\'' +
                    ", vip_total=" + vip_total +
                    '}';
        }
    }

    public class Domain {
        public long id;
        public String name;
        public String owner;

        @Override
        public String toString() {
            return "Domain{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", owner='" + owner + '\'' +
                    '}';
        }
    }

    @Override
    public String toString() {
        return "DomainBean{" +
                "status=" + status +
                ", info=" + info +
                ", domains=" + Arrays.toString(domains) +
                '}';
    }
}

都重写的toString方法是为了打印出来更加清晰而已。

3. 构造请求并且发送请求:

private void retrofitTest() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://xxx.cn")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GetDomainService service = retrofit.create(GetDomainService.class);
        Call call = service.getDomain("xxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxx");
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                Log.e("onResponse", "" + response.body().toString());
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.e("onFailure", "" + t.getMessage());
            }
        });
    }

刚才说了,定义请求接口的请求方式@POST时,里面是请求路径,并不是完整的地址,所以要调用baseUrl方法声明请求地址。通过Retrofit的包装,得到Call对象,用过okhttp的同学就立刻发现,okhttp最后也是通过Call对象发送请求,不过这个Call不是okhttp的Call,不过里面的方法大体一样,最后就调用Call对象的enqueue方法或者execute方法进行发送请求。

4. 最后请求结果:

01-06 01:30:31.485 15453-15453/com.example.administrator.retrofittest E/onResponse: DomainBean{status=Status{code='1', message='Action completed successful', created_at='2019-01-06 01:30:31'}, info=Info{domain_total=1, all_total=1, mine_total=1, share_total='0', vip_total=0}, domains=[Domain{id=xxx, name='xxx.com', owner='[email protected]'}]}

撸代码时有个小插曲,代码中我用到了GsonConverterFactory类进行请求结果的转换,为什么呢?因为如果不转成Json,直接用String会报错,之前的代码是这样的:

public interface GetDomainService {

    @FormUrlEncoded
    @POST("/Domain.List")
    Call getDomain(@Field("login_token") String login_token, @Field("format") String format);
}

private void retrofitTest() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://xxx.cn")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        GetDomainService service = retrofit.create(GetDomainService.class);
        Call call = service.getDomain("xxxxxxxxxxxxxxxxxxxxx", "xxxx");
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                Log.e("onResponse", "" + response.body().toString());
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.e("onFailure", "" + t.getMessage());
            }
        });
    }

没有用到javabean,我直接返回String简单点,但是报错提示结果不能转String,所以转Json,但是发现教程上用的GsonConverterFactory类找不到,教程上也只写着

  • 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
    全部没有写版本号。。。。。最后google到是
compile 'com.squareup.retrofit2:converter-gson:2.0.2'

加上就能正常编译解析json。

但是如果我只想单单解析成String,之后的操作想另外处理,或者如果接口请求失败,返回的就不一定是json了,那怎么办?这个需要再深入了解这个网络框架。

你可能感兴趣的:(Retrofit初探)