Retrofit初探

作者: csexttt | 来源:发表于2019-01-06 12:29 被阅读0次

    之前了解到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<DomainBean> 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<DomainBean> call = service.getDomain("xxxxxxxxxxxxxxxxxxxxxxxx", "xxxxxx");
            call.enqueue(new Callback<DomainBean>() {
                @Override
                public void onResponse(Call<DomainBean> call, Response<DomainBean> response) {
                    Log.e("onResponse", "" + response.body().toString());
                }
    
                @Override
                public void onFailure(Call<DomainBean> 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='xxx@qq.com'}]}
    

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

    public interface GetDomainService {
    
        @FormUrlEncoded
        @POST("/Domain.List")
        Call<String> 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<String> call = service.getDomain("xxxxxxxxxxxxxxxxxxxxx", "xxxx");
            call.enqueue(new Callback<String>() {
                @Override
                public void onResponse(Call<String> call, Response<String> response) {
                    Log.e("onResponse", "" + response.body().toString());
                }
    
                @Override
                public void onFailure(Call<String> 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初探

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