Retrofit网络框架入门使用

1.简单介绍

retrofit事实上就是对okhttp作了进一步一层封装优化。php

咱们仅仅需要经过简单的配置就能使用retrofit来进行网络请求了。css

Retrofit可以直接返回Bean对象,好比假设咱们进行一个网络接口的请求。返回来一串json字符串。那么这个时候通常咱们都要拿到这个json字符串后进行解析获得相应的Bean对象,Retrofit仅仅要依赖一下Gson的转换库而后进行简单的配置就可以直接拿到Bean对象了,不需要咱们本身去解析。html

接触过OKHttp的人会发现,Retrofit和OKHttp的代码有些地方有很大的相似度。java

他的性能很的棒,国外大牛(被墙了)已经作过測例如如下图:android

这里写图片描写叙述

看了这个图以后你有什么想法?ios

Talk is cheap, show me the code!git

github

2.高速使用

在实际项目开发中get、post请求使用居多。那咱们以get请求来作个入门小案例。json

http://ip.taobao.com/service/getIpInfo.php?ip=8.8.8.8

以上链接是一个get请求方式。參数在地址后面使用“?”进行名值对的拼接。请求的结果是一个json字符串数据。例如如下api

{"code":0,"data":{"country":"\u7f8e\u56fd","country_id":"US","area":"","area_id":"","region":"","region_id":"","city":"","city_id":"","county":"","county_id":"","isp":"","isp_id":"","ip":"8.8.8.8"}}

来个简单的Demo界面例如如下:
功能很easy,一个输入框输入IP地址,而后获取IP地址所在的国家。


这里写图片描写叙述

1)环境的配置

现在预计不多人用eclipse作项目开发了。eclipse的方式就不另赘述了(GitHub上也是有jar依赖下载的)。咱们这里的开发工具是用的Android Studio,在 GitHub项目地址:https://github.com/square/retrofit可以找到Gradle的依赖代码:
加入两个依赖:retrofit依赖。和gson转换器。

compile 'com.squareup.retrofit2:retrofit:2.1.0'//眼下最新的版本号
compile 'com.squareup.retrofit2:converter-gson:2.1.0'//加入好这个依赖后咱们就可以进行数据转换器的配置了。retrofit内部就会帮咱们去转换json字符串为Java对象

在AS里面的效果例如如下:
这里写图片描写叙述

converter-gson依赖的版本号号与retrofit依赖版本号号保持一致。咱们在GitHub上可以看到。他们在同一个project里面的。

2)代码

布局很easy就不另贴代码了。类也很少參看如下的包结构图
这里写图片描写叙述

Retrofit操做步骤

① 先把接口返回来的数据bean对象写好。

可以直接使用工具转化。如GsonFormat工具

public class IpInfo {
    public int code;
    public DataBean data;

    public static class DataBean {
        public String country;
        public String country_id;
        public String area;
        public String area_id;
        public String region;
        public String region_id;
        public String city;
        public String city_id;
        public String county;
        public String county_id;
        public String isp;
        public String isp_id;
        public String ip;

    }

}
② 定义API接口

通常来说都是处理遵循RESTful接口规范的http接口,咱们需要把接口转化为Java Interface。

/** * 这个接口就是普通的借口类,但是看到里面的方法来,会有一些注解定义相关的功能 * 如@GET定义请求方式为get请求方式,假设有參数可以使用@Query、@QueryMap定义 */ public interface IpService { /** * @return 固定返回值为Call。当中泛型指定是进行请求后返回终于得数据类型。

*/ @GET("getIpInfo.php") //@GET 定义网络请求方式 Call<IpInfo> getIpInfo(@Query("ip") String ip); //@Query("ip") 指的是传入的參数名为ip。值为调用方法传入的值形參ip }
③ 初始化Retrofit,建立接口实例,进行异步请求

代码凝视灰常仔细了

/** *Retrofit简单有用案例 * * 採用http://ip.taobao.com/service/getIpInfo.php?ip=202.178.10.2 地址进行查询 */ public class MainActivity extends AppCompatActivity { public static final String baseUrl = "http://ip.taobao.com/service/"; private TextView tvResult; private EditText etIp; IpService ipService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tvResult = (TextView) findViewById(R.id.tv_result); etIp = (EditText) findViewById(R.id.et_ip); initRetrofit(); } /** * 初始化Retrofit实例。并建立接口类。 * 注意:IpService不需要咱们去实现。直接Retrofit=类有create方法生成。 */ private void initRetrofit() { //建立Retrofit的实例,把Gson转换器设置下 Retrofit retrofit = new Retrofit .Builder() .baseUrl(baseUrl)//设置API的基础地址 .addConverterFactory(GsonConverterFactory.create())//设置后才才支持json字符串转化为Bean .build(); //使用Retrofit的create方法传入建立接口实例 ipService = retrofit.create(IpService.class); } /** * 布局中查询button配置的点击事件 * @param view */ public void check(View view) { String ip = etIp.getText().toString(); if (TextUtils.isEmpty(ip)) { Toast.makeText(this, "ip 不能为空", Toast.LENGTH_SHORT).show(); return; } //调用接口声明的方法 Call<IpInfo> ipInfoCall = ipService.getIpInfo(ip); //call可以直接调用异步方法。进行结果获取。

需要传入接口回调Callback, ipInfoCall.enqueue(new Callback<IpInfo>() { @Override public void onResponse(Call<IpInfo> call, Response<IpInfo> response) { //推断网络请求是否成功。网络请求返回code为[200..300)那么与后台链接成功。

不然链接失败 if (response.isSuccessful()) { //直接拿到JavaBean IpInfo ipInfo = response.body(); //这里直接可以进行UI操做。OKHttp是不行的哦 tvResult.setText(ipInfo.getData().getCountry()); } else { //请求失败。

假设代码执行到这里来讲明是有跟后台握手的,是后台处理有问题,如404(没有资源),500(后台报错了) tvResult.setText("查询失败!! -->code="+response.code()); } } @Override public void onFailure(Call<IpInfo> call, Throwable t) { //请求失败。如,没有声明网络权限、没有网络、或者是Retrofit 异常内部处理异常(如Gson解析失败)也是会到这里 t.printStackTrace(); tvResult.setText("查询失败:"+t.getCause()); } }); } }

3.常常使用注解

GET:get 请求方式
POST:post请求方式
Query:定义get请求參数
QueryMap:定义get请求參数
Field:定义post请求參数
FieldMap:定义post请求參数
Header:定义头參数
HeaderMap:定义头參数
Headers:定义头參数
Path:动态路径
来看看代码是怎么实现的:

public interface SampleApi { //----------------------GET 请求方式 start -------------------------------- /** * 注解:GET。QUERY,QUERYMAP 的使用 */ /** * get 请求固定參数形式 * * @return */ @GET("demo?

username=zhanghsan&password=123455") Call<SampleResponse> getFun(); /** * 使用@Query注解进行參数传递 * * @param username * @param password * @return */ @GET("demo") Call<SampleResponse> getFun(@Query("username") String username, @Query("password") String password); /** * 使用@QueryMap注解 Map集合进行參数传递 * * @param params * @return */ @GET("demo") Call<SampleResponse> getFun(@QueryMap Map<String, Object> params); //----------------------GET 请求方式 end -------------------------------- //----------------------POST 请求方式 start -------------------------------- /** * POST,Field,FieldMap,FormUrlEncoded(POST 方式请求有參数的时候必定不要忘记了这个注解) */ /** * post使用@Query注解进行參数传递 * * @param username * @param password * @return */ @FormUrlEncoded @POST("demo") Call<SampleResponse> postFun(@Field("username") String username, @Field("password") String password); /** * POST使用@FiledMap Map集合进行參数传递 * * @param params * @return */ @FormUrlEncoded @POST("demo") Call<SampleResponse> postFun(@FieldMap Map<String, Object> params); //----------------------POST 请求方式 end -------------------------------- //----------------------head參数加入start -------------------------------- /** * Headers。Header,HeaderMap * */ /** * 有些接口需要传送一些操做client系统的信息,比方系统类型。系统版本号等例如如下 * * @param username * @param password * @return */ @Headers( {"os:Android" , "osversion:5.0" }) @FormUrlEncoded @POST("demo") Call<SampleResponse> postFunWithHead(@Field("username") String username, @Field("password") String password); /** * 有些接口需要传送一些操做client系统的信息,比方系统类型。系统版本号等例如如下 * * @param username * @param password * @return */ @FormUrlEncoded @POST("demo") Call<SampleResponse> postFunWithHead(@Header("os") String os, @Header("osversion") String osversion, @Field("username") String username, @Field("password") String password); /** * 有些接口需要传送一些操做client系统的信息,比方系统类型,系统版本号等例如如下 * * @param headParams head 參数。键值对的形式存储到map集合中去 * @param username * @param password * @return */ @FormUrlEncoded @POST("demo") Call<SampleResponse> postFunWithHead(@HeaderMap Map<String, String> headParams, @Field("username") String username, @Field("password") String password); //----------------------head參数加入end -------------------------------- //----------------------path 注解 -------------------------------- /** * Path注解使用时在请求方式注解后面的URL设置一个占位符,使用大括号包裹。

在方法形參类型前使用@Path("占位符")。 */ @FormUrlEncoded @POST("{path}") Call<SampleResponse> postFunWithHead(@Path("path") String path, @HeaderMap Map<String, String> headParams, @Field("username") String username, @Field("password") String password); }

Activity代码

public class SampleActivity extends AppCompatActivity { EditText etName; EditText etPassword; TextView tvResult; SampleApi sampleApi; SampleCallBack callback; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sample); etName = (EditText) findViewById(R.id.et_name); etPassword = (EditText) findViewById(R.id.et_password); tvResult = (TextView) findViewById(R.id.tv_result); //使用链式调用创建 sampleApi = new Retrofit .Builder() .baseUrl("http://10.0.2.2:8080/") .addConverterFactory(GsonConverterFactory.create()) .build() .create(SampleApi.class); callback = new SampleCallBack(); } /** * button点击事件 * * @param view */ public void submit(View view) { tvResult.setText("正在请求...."); String name = etName.getText().toString(); String password = etPassword.getText().toString(); if (TextUtils.isEmpty(name) || TextUtils.isEmpty(password)) { Toast.makeText(this, "參数不能为空", Toast.LENGTH_SHORT).show(); return; } Call<SampleResponse> call; switch (view.getId()) { case R.id.btn_get: call = sampleApi.getFun(name, password); call.enqueue(callback); break; case R.id.btn_post: call = sampleApi.postFun(name, password); call.enqueue(callback); break; case R.id.btn_head: // call = sampleApi.postFunWithHead(name, password);//第一种,直接静态定义方式。看接口方法 // call = sampleApi.postFunWithHead("ios","10.10.10",name, password);//另一种,可以动态配置值得方式 Map<String, String> map = new HashMap<>(); map.put("os", "android"); map.put("osversion", "9.9.9999999"); // call = sampleApi.postFunWithHead(map, name, password);//第三种,可以动态配置參数和值得形式 call = sampleApi.postFunWithHead("demo",map, name, password);//第四种,结合Path定义路径 call.enqueue(callback); break; } } /** * @param result * 显示结果 */ public void showResult(String result) { tvResult.setText(result); } /** * 回调实现类 */ public class SampleCallBack implements Callback<SampleResponse> { @Override public void onResponse(Call<SampleResponse> call, Response<SampleResponse> response) { //推断网络请求是否成功。网络请求返回code为[200..300)那么与后台链接成功。不然链接失败 if (response.isSuccessful()) { //直接拿到JavaBean SampleResponse sampleResponse = response.body(); //这里直接可以进行UI操做。OKHttp是不行的哦 showResult(sampleResponse.toString()); } else { //请求失败。

假设代码执行到这里来讲明是有跟后台握手的,是后台处理有问题,如404(没有资源),500(后台报错了) showResult("查询失败。! -->code=" + response.code()); } } @Override public void onFailure(Call<SampleResponse> call, Throwable t) { //请求失败。如。没有声明网络权限、没有网络、或者是Retrofit 异常内部处理异常(如Gson解析失败)也是会到这里 t.printStackTrace(); showResult("查询失败:" + t.getCause()); } } }

执行效果

这里写图片描写叙述

4.URL操做注意事项

拼接注意,建议baseUrl用“/”结尾。接口中请求方式后面的url不用”/”开头

样例:baseUrl=http://10.0.2.2:8080/market/ url=home

错误案例

案例一:
baseUrl=http://10.0.2.2:8080/market url=home
—>http://10.0.2.2:8080/home
分析:默认用最后一个斜线去拼接

案例二:
baseUrl=http://10.0.2.2:8080/market url=/home
—>http://10.0.2.2:8080/home
分析:url中開始的斜线表明主机地址http://10.0.2.2:8080

源码下载

Retrofit还可以实现上传下载以及 结合RxJava使用,等下回分解!

相关文章
相关标签/搜索