Retrofit2.0基本应用初探

本文主要是讲解了Retrofit的使用以下几方面的介绍
使用get方式,@Path 注解来构建完整的URL
.使用get方式,@Query,@Querymap 注解来构建完整的URL
使用post 方式 ,@Field ,@Fieldmap 注解来构建完整的URL。

Retrofit是什么?
Retrofit就是一个Http请求库,和其它Http库最大区别在于通过大范围使用注解简化Http请求。目前Retrofit 2.0底层是依赖OkHttp实现的,也就是说Retrofit本质上就是对OkHttp的更进一步封装。
Retrofit简单示例使用
要想使用retrofit,首先需要添加以下相关的依赖:

    compile 'com.squareup.retrofit2:retrofit:2.1.0'
    compile 'com.squareup.retrofit2:converter-gson:2.0.2'
    compile 'com.google.code.gson:gson:2.6.1'
    compile 'com.squareup.okhttp3:okhttp:3.2.0'

我们请求的URL地址为:https://api.github.com/repos/square/retrofit/contributors 这是一个restful url格式的请求,而retrofit非常适合于这种请求

创建API接口
在retrofit中通过一个Java接口作为http请求的api接口。

public interface ApiService {
    @GET("repos/{owner}/{repo}/contributors")
    Call<List<ResponseBody>> getInfo(@Path("owner") String owner, @Path("repo") String repo);
}

创建retrofit实例
  在这里baseUrl是在创建retrofit实力的时候定义的,我们也可以在API接口中定义完整的url。在这里建议在创建baseUrl中以”/”结尾,在API中不以”/”开头和结尾。

Retrofit retrofit=new Retrofit.Builder()
                .baseUrl("https://api.github.com/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

创建retrofit实例,我们通过addConverterFactory指定一个factory来对响应反序列化,因为笔者一直用Gson来解析数据,所以在本篇一开始我就把为retrofit添加gson转换器的依赖给添加进来了·就是:

compile ‘com.squareup.retrofit2:converter-gson:2.0.2’
compile ‘com.google.code.gson:gson:2.6.1’

当然除了gson以外,还提供了以下的选择:

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-scalar

现在API接口跟retrofit实例都创建好了·我们就试着去调用,当然在我们创建API接口之前我们需要根据服务器返回的数据类型创建一个Java类ResponseBody,用来保存接收到的数据。

 private String login;
    private int id;

    public String getLogin() {
        return login;
    }

    public void setLogin(String login) {
        this.login = login;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

这个接口返回的数据字段很多·为了简单点·我就选了login跟id这2个字段.

调用API接口

在调用API接口请求后,获得一个json字符串,通过Gson进行解析,获得login以及id。

ApiService service=retrofit.create(ApiService.class);

        Call<List<ResponseBody>> call =service.getInfo("square","retrofit");
        call.enqueue(new Callback<List<ResponseBody>>() {
            @Override
            public void onResponse(Call<List<ResponseBody>> call, Response<List<ResponseBody>> response) {
                textView.setText(response.body().get(1).getLogin());
            }

            @Override
            public void onFailure(Call<List<ResponseBody>> call, Throwable t) {

            }
        });
    }

通过调用创建的API接口,请求的数据显示在TextView上,说明了这次请求成功。
总结:
使用get方式,@Path 注解来构建完整的URL,首先请求的URL是具有restful风格的url比如上面例子的url=”https://api.github.com/repos/square/retrofit/contributors”,然后在创建API接口的时候我们是用注解的方式来区别get或post请求,比如上面的例子@GET(“repos/{owner}/{repo}/contributors”),对于{owner}与{repo} 我们可以这么理解,我们可以理解为他只是一个占位符,然后我们通过getInfo(@Path(“owner”) String owner, @Path(“repo”) String repo)方法请求的时候所填的值给替换上去,这样我们就构成了如上的完整的url.

对于大多数开发公司来说后台给的url不是具有restful风格的,比如像这种url=http://apis.juhe.cn/mobile/get?phone=13429667914&key=46066e52ff348681e2e3b22669c0cd89 我们改怎么处理呢·看以下示例

使用get方式,@Query 注解来构建完整的URL

首先我们通过这个url给的数据写一个java实体类给来存储数据

public class Info {
        private String resultcode;
        private String reason;
        private ResultBean result;
        private int error_code;
        public String getResultcode() {
            return resultcode;
        }
        public void setResultcode(String resultcode) {
            this.resultcode = resultcode;
        }
        public String getReason() {
            return reason;
        }
        public void setReason(String reason) {
            this.reason = reason;
        }
        public ResultBean getResult() {
            return result;
        }
        public void setResult(ResultBean result) {
            this.result = result;
        }
        public int getError_code() {
            return error_code;
        }
        public void setError_code(int error_code) {
            this.error_code = error_code;
        }
        public static class ResultBean {
            private String province;
            private String city;
            private String areacode;
            private String zip;
            private String company;
            private String card;
            public String getProvince() {
                return province;
            }
            public void setProvince(String province) {
                this.province = province;
            }
            public String getCity() {
                return city;
            }
            public void setCity(String city) {
                this.city = city;
            }

            public String getAreacode() {
                return areacode;
            }
            public void setAreacode(String areacode) {
                this.areacode = areacode;
            }
            public String getZip() {
                return zip;
            }
            public void setZip(String zip) {
                this.zip = zip;
            }
            public String getCompany() {
                return company;
            }
            public void setCompany(String company) {
                this.company = company;
            }
            public String getCard() {
                return card;
            }
            public void setCard(String card) {
                this.card = card;
            }
        }
}

然后我们创建API接口

public interface ApiService {
    @GET("mobile/get")
    Call<Info> getInfo1(@Query("phone") String phone,@Query("key") String key);

API接口创建好了·我们创建retrofit的实例如下:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://apis.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

接口跟实例都创建好了·我们调用获取数据然后显示在TextView上

 ApiService service = retrofit.create(ApiService.class);

        Call<Info> call = service.getInfo1("15201339282", "46066e52ff348681e2e3b22669c0cd89");
        call.enqueue(new Callback<Info>() {
            @Override
            public void onResponse(Call<Info> call, Response<Info> response) {
                textView.setText(response.body().getResult().getCity());
            }

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

            }
        });
    }

经过运行项目我们的TextView上显示了城市名称,这样我们的请求成功

上面是使用get方式,@Query 注解来构建完整的URL,我们还可以用,@Querymap注解来构建完整的url如下:

API接口

public interface ApiService {
    @GET("mobile/get")
    Call<Info> getInfo2(@QueryMap Map<String,String> map);
    }

跟上面用@Query注解构建url不同的是·这里在getInfo2方法中传的参数是一个 Map集合
创建retrofit实例跟上面的例子一样的·这里就不贴出来了·然后调用如下:

 Map<String, String> map = new HashMap<>();
        map.put("phone", "13762529061");
        map.put("key", "46066e52ff348681e2e3b22669c0cd89");
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://apis.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService service = retrofit.create(ApiService.class);
        Call<Info> call = service.getInfo2(map);
        call.enqueue(new Callback<Info>() {
            @Override
            public void onResponse(Call<Info> call, Response<Info> response) {
                Log.d("TAG", response.body().getResultcode());
                textView.setText(response.body().getResult().getCity());
            }

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

            }
        });
    }

如上构建完整的url是:url=http://apis.juhe.cn/mobile/get?phone=13762569061&key=46066e52ff348681e2e3b22669c0cd89

如上url我们还可以使用post 方式 ,@Field ,@Fieldmap 注解来构建完整的URL。
API接口

public interface ApiService {
    @FormUrlEncoded
    @POST("mobile/get")
    Call<Info> getInfo3(@Field("phone") String phone , @Field("key") String key)}

创建retrofit实例跟调用

  Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://apis.juhe.cn/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        ApiService service = retrofit.create(ApiService.class);
        Call<Info> call = service.getInfo3("13762569061", "46066e52ff348681e2e3b22669c0cd89");
        call.enqueue(new Callback<Info>() {
            @Override
            public void onResponse(Call<Info> call, Response<Info> response) {
                textView.setText(response.body().getResult().getCity());
            }

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

            }
        });

显示的结果跟上面的例子是一样的只是使用get跟post的方法的区别,至于使用@Fieldmap 注解来构建url 也就是在getInfo()方法中传入的的参数是一个map集合,参照@Querymap注解来构建完整url的例子。

写了这么多大家看到的请求方式都是异步请求call.enqueue(),当然需要同步请求的话可以使用时call.execute()执行一个同步请求.这里代码就不贴出来了,相信执行很简单的.

clone的使用
当我们想利用call的实例多次请求的时候,我们发现会报这样的错误:

 Process: com.example.john.retrofit2, PID: 16999
                                                                            java.lang.IllegalStateException: Already executed.
                                                                                at retrofit2.OkHttpCall.enqueue(OkHttpCall.java:78)
                                                                                at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.enqueue(ExecutorCallAdapterFactory.java:60)
                                                                                at com.example.john.retrofit2.MainActivity.getDataFromService3(MainActivity.java:130)
                                                                                at com.example.john.retrofit2.MainActivity$7.onClick(MainActivity.java:179)

因为在这里无论是同步操作还是异步操作每一个call对象实例只能被执行一次,不然的话就会抛出以上的异常.如果我们真有需求要执行多次·那么retrofit提供了一个clone给我们,表面意思是克隆.我们该这样子做:

Call<Info> callClone= call.clone();
        callClone.enqueue(new Callback<Info>() {}
或者
Call<Info> callClone= call.clone();
        callClone.execute();

也就是克隆一个实例执行同步或者异步请求.

到此使用Retrofit最基本的用法的使用已经完结,需要更深入的了解Retrofit的使用可以移至http://blog.csdn.net/lmj623565791/article/details/51304204

本篇博客demo地址:https://github.com/MrXiaoChao/Retrofit2 欢迎围观

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值