Retrofit简介
什么是Retrofit?
官方解释:一个为Java和Android提供的类型安全的HTTP请求客户端。
补充:Retrofit是 Square 公司开发的一个用于网络请求的开源库,内部封装了OkHttp,简化了我们的网络请求配置。
下面,附上官网链接方便各位查阅学习。
Retrofit使用实例
今天,Blogger用一个简单的实例来介绍下Retrofit的使用。
数据来源
使用的数据接口来自 GankIO(干货集中营)
数据接口链接: http://gank.io/api/data/数据类型/请求个数/第几页
数据类型: 福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all
请求个数: 数字,大于0
第几页:数字,大于0
接下来,我们想得到『福利』类型的第1页、前3条的数据,链接补全如下:
http://gank.io/api/data/福利/3/1
在浏览器打开链接后,我们可以看到数据的返回情况,如下图所示(红色文字是『截图注释』):
request_result.png
接下来我们要做的就是:在Android客户端使用Retrofit请求数据,之后用Log将数据打印出来(证明我们拿到数据了)。
Retrofit数据请求步骤
1. 添加Retrofit库。
在应用工程下的build.gradle文件中添加依赖库。
dependencies { ...... // Retrofit compile 'com.squareup.retrofit2:retrofit:2.1.0' // Retrofit - Gson数据转换工具 compile 'com.squareup.retrofit2:converter-gson:2.1.0'}
2. 建立数据模型。
看到浏览器返回的数据,我们可以将数据层次分为两级,最外层为第一级,包含一个『数据反馈状态』和一个『数据列表』,额外添加toString()方法方便Log打印。(第一级数据模型如下所示):
/** * @ClassName: GankIOData * @Description: GankIO - 数据模型 * @Author: wangnan7 * @Date: 2016/12/30 下午5:27 */public class GankIOData implements Serializable { public boolean error; /* 数据是否出错 */ public List<GankIOBaseData> results; /* 数据列表 */ @Override public String toString() { return "GankIOData{" + "error=" + error + ", results=" + results + '}'; } }
第二级数据模型是每条数据的详情信息,额外添加toString()方法方便Log打印,如下所示:
/** * @ClassName: GankIOBaseData * @Description: GankIO - 基本数据模型 * @Author: wangnan7 * @Date: 2016/12/30 下午5:29 */public class GankIOBaseData implements Serializable { public String _id; /* 数据ID (例:"_id": "5865ad4e421aa94dbe2ccdb0")*/ public String createdAt; /* 创建时间 (例:"createdAt": "2016-12-30T08:41:50.830Z")*/ public String desc; /* 描述 (例:"desc": "12-30") */ public String publishedAt; /* 发布时间 (例:"publishedAt": "2016-12-30T16:16:11.125Z")*/ public String source; /* 来源 (例:"source": "chrome")*/ public String type; /* 类型 (例:"type": "\u798f\u5229")*/ public String url; /* 图片链接 (例:"url": "http://ww4.sinaimg.cn/large/610dc034jw1fb8iv9u08ij20u00u0tc7.jpg")*/ public boolean used; /* 是否被使用过 (例:"used": true)*/ public String who; /* 数据提供者 (例:"who": "daimajia")*/ @Override public String toString() { return "GankIOBaseData{" + "_id='" + _id + '\'' + ", createdAt='" + createdAt + '\'' + ", desc='" + desc + '\'' + ", publishedAt='" + publishedAt + '\'' + ", source='" + source + '\'' + ", type='" + type + '\'' + ", url='" + url + '\'' + ", used=" + used + ", who='" + who + '\'' + '}'; } }
3. 建立服务接口。
我们将之前的接口链接(http ://gank.io/api/data/数据类型/请求个数/第几页)拆分为两部分:
第1部分:http://gank.io/ (主机地址部分)
第2部分:api/data/数据类型/请求个数/第几页 (路径及参数部分)
接下来,根据第2部分建立数据服务接口,代码如下:
/** * @ClassName: RetrofitService * @Description: 干货集中营 - 数据服务接口 * @Author: wangnan7 * @Date: 2016/12/30 下午5:40 */public interface RetrofitService { /** * 获取GankIO数据(http://gank.io/api/data/数据类型/请求个数/第几页) * * @param type 数据类型:福利 | Android | iOS | 休息视频 | 拓展资源 | 前端 | all * @param count 请求个数:数字,大于0 * @param page 第几页: 数字,大于0 */ @GET("api/data/{type}/{count}/{page}") Call<GankIOData> getGankIOData(@Path("type") String type, @Path("count") int count, @Path("page") int page); }
@GET:当前接口请求为Get请求。
@Path:路径补全。例:@Path("type") String type ,我们传入的type形参值会填入{type}中补全路径。
4. 构建Retrofit对象并请求接口数据。
在MainActivity中创建Retrofit对象并进行接口数据请求,代码如下:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Retrofit retrofit = new Retrofit.Builder() /* 创建一个Retrofit建造者 */ .baseUrl("http://gank.io/") /* 传入请求接口的主机地址 */ .addConverterFactory(GsonConverterFactory.create()) /* 添加Gson数据转换 */ .build(); /* 建立Retrofit对象 */ /* 创建服务接口实现类 */ RetrofitService service = retrofit.create(RetrofitService.class); /* 补全接口请求参数,得到Call对象,执行完此步Retrofit的作用就已经完成了。(Call是Okhttp中的一个概念,代表了一个实际的HTTP请求) */ Call<GankIOData> call = service.getGankIOData("福利", 3, 1); /* 请求网络,异步获取数据 */ call.enqueue(new Callback<GankIOData>() { @Override public void onResponse(Call<GankIOData> call, Response<GankIOData> response) { if(response.isSuccessful()){ /* 检查返回的网络状态码是否在[200..300),一般200最为常见,300+表示请求的url被重定向了... */ GankIOData data = response.body(); /* 获取数据模型 */ Log.e("TAG", data.toString()); /* 打印数据 */ } } @Override public void onFailure(Call<GankIOData> call, Throwable t) { } }); } }
5. 添加联网权限。
不要忘记在AndroidManifest文件中添加联网权限手累,就不打三遍了O(∩_∩)O
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.testing.retrofitdemo"> <!-- 联网权限 --> <uses-permission android:name="android.permission.INTERNET"/> ...... </manifest>
最后运行下程序,我们的Log工具就将数据打印出来了。
12-30 17:48:57.394 6915-6915/com.example.testing.retrofitdemo E/TAG: GankIOData{error=false, results=[GankIOBaseData{_id='5865ad4e421aa94dbe2ccdb0', createdAt='2016-12-30T08:41:50.830Z', desc='12-30', publishedAt='2016-12-30T16:16:11.125Z', source='chrome', type='福利', url='http://ww4.sinaimg.cn/large/610dc034jw1fb8iv9u08ij20u00u0tc7.jpg', used=true, who='daimajia'}, GankIOBaseData{_id='58645be0421aa94dbbd82bac', createdAt='2016-12-29T08:42:08.389Z', desc='12-29', publishedAt='2016-12-29T11:56:56.946Z', source='chrome', type='福利', url='http://ww4.sinaimg.cn/large/610dc034gw1fb7d9am05gj20u011hq64.jpg', used=true, who='daimajia'}, GankIOBaseData{_id='58632374421aa9723d29b9ba', createdAt='2016-12-28T10:29:08.507Z', desc='12-28', publishedAt='2016-12-28T11:57:39.616Z', source='chrome', type='福利', url='http://ww1.sinaimg.cn/large/610dc034gw1fb6aqccs3nj20u00u0wk4.jpg', used=true, who='daimajia'}]}
至此,我们的数据就请求成功了。
Retrofit混淆配置
我们一般在给应用打包上线时会给代码添加混淆配置,一来是为了防止别人反编译,二来是可以给apk文件瘦身。
混淆开启方法,在应用工程下的build.gradle文件中,找到minifyEnabled配置项并设置为true,如下所示(注意这里是release配置,debug运行时混淆开关还是关着的):
android { ...... buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }
对于Retrofit,开启混淆开关后,我们还要在混淆文件(proguard-rules.pro)中添加一些混淆配置,在Retrofit官网中也有混淆的相关配置说明,如下所示:
如果你要在你的工程中使用混淆,需要添加以下几行配置项:
# Platform calls Class.forName on types which do not exist on Android to determine platform.-dontnote retrofit2.Platform# Platform used when running on RoboVM on iOS. Will not be used at runtime.-dontnote retrofit2.Platform$IOS$MainThreadExecutor# Platform used when running on Java 8 VMs. Will not be used at runtime.-dontwarn retrofit2.Platform$Java8# Retain generic type information for use by reflection by converters and adapters.-keepattributes Signature# Retain declared checked exceptions for use by a Proxy instance.-keepattributes Exceptions
虽然官网给出了混淆配置,但还是想吐槽两句...
官网给的混淆配置其实并不完全,我们都知道Retrofit是对Okhttp的封装,Okhttp不需要添加混淆配置吗?另外,我们使用了Gson转换,Gson不需要添加混淆配置吗?还有,如果我们bean目录的数据模型的字段被混淆了,还能和服务端返回的数据对上吗?
第一点:如果不添加Okhttp的混淆配置,编译到okio时会报错。
第二点:此处Gson可以不添加混淆配置(这意味着Gson将会是混淆的)。
第三点:要保证我们的数据模型不被混淆,否则得到的数据全是null。
最后,给各位列一下我的混淆文件中的相关配置:
# Retrofit-dontnote retrofit2.Platform -dontnote retrofit2.Platform$IOS$MainThreadExecutor -dontwarn retrofit2.Platform$Java8 -keepattributes Signature -keepattributes Exceptions# okhttp-dontwarn okio.**# Gson-keep class com.example.testing.retrofitdemo.bean.**{*;} # 自定义数据模型的bean目录
配置之后,打包混淆后的release版应用就能拿到数据了。
Retrofit进阶推荐
最后,给想要继续进阶Retrofit的小伙伴们推荐一篇博客:
【腾讯Bugly干货】深入浅出 Retrofit,这么牛逼的框架你们还不来看看?
作者:梦想编织者灬小楠
链接:https://www.jianshu.com/p/a4d15608aaf7