Retrofit学习入门
Retrofit的使用
- 设置权限与添加依赖
- 定义请求接口
- 通过创建一个retrofit生成一个接口的实现类(动态代理)
- 调用接口请求数据
设置权限与添加依赖
权限:首先确保在AndroidManifest.xml中请求了网络权限 :
<uses-permission android:name="android.permission.INTERNET" />
(2)Studio用户,在app/build.gradle文件中添加如下代码:
dependencies {
compile'com.squareup.retrofit2:retrofit:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta3'
}
定义请求接口
public interface GankioService {
@GET("data/福利/10/{page}")
Call<GirlData> getGirls(@Path("page") int page);
@GET("data/Android/10/{page}")
Call<AndroidData> getAndroidData(@Path("page") int page);
}
请求的URL可以在函数中使用替换块和参数进行动态更新,替换块是{ and }包围的字母数字组成的字符串,相应的参数必须使用相同的字符串被@Path进行注释
然后创建一个retrofit
public static GankioService buildGankioService() {
if (mGankioService == null) {
Retrofit retfGank = new Retrofit.Builder()
.baseUrl("http://gank.io/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
mGankioService = retfGank.create(GankioService.class);
}
return mGankioService;
}
retfGank.create(GankioService.class)用到了动态代理
大家一看就发现了 create方法返回了一个动态代理对象,那么动态代理是什么呢 :
—在运行时, 动态代理类 实现了一个或者一组接口,目的是,其中任何一个接口的实例的方法调用将会被指派到统一的另一个接口的方法中。
InvocationHandler 中覆写的 invoke() 方法,在进行原本的方法调用之前或者之后,可以做点事情。
所以当我们调用 httpStores.getUser(hashMap);的时候其实是走了动态代理的invoke方法,在这里Retrofit巧妙的理由注解把接口转换成了一个HTTP请求
调用接口请求数据
private void loadFromInternet(int page) {
start = page;
final Call<GirlData> girlDataCall = mService.getGirls(page);
girlDataCall.enqueue(new Callback<GirlData>() {
@Override
public void onResponse(Call<GirlData> call, Response<GirlData> response) {
mGirlData = response.body();
List<Girl> newGirls = mGirlData.getGirls();
// check if newGirls should be added into local girls
if (checkShouldAdded(newGirls)){
addGirlsToDB(newGirls);
}else{
shouldLoadFromInternet = false;
}
mView.showMore(newGirls);
mView.finishRefresh();
}
@Override
public void onFailure(Call<GirlData> call, Throwable t) {
mView.finishRefresh();
mView.showSnackBar();
}
});
}
其中GirlData是由接口返回的json数据格式决定的
public class GirlData {
/**
* error : false
* results : [{"_id":"56eb5db867765933d9b0a8fc","_ns":"ganhuo","createdAt":"2016-03-18T09:45:28.259Z","desc":"3.18","publishedAt":"2016-03-18T12:18:39.928Z","source":"chrome","type":"福利","url":"http://ww1.sinaimg.cn/large/7a8aed7bjw1f20ruz456sj20go0p0wi3.jpg","used":true,"who":"张涵宇"},{"_id":"56e8d0bb67765933d8be90be","_ns":"ganhuo","createdAt":"2016-03-16T11:19:23.692Z","desc":"3.16","publishedAt":"2016-03-17T11:14:16.306Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/7a8aed7bjw1f1yjc38i9oj20hs0qoq6k.jpg","used":true,"who":"张涵宇"},{"_id":"56e8ce3967765933d8be90bd","_ns":"ganhuo","createdAt":"2016-03-16T11:08:41.957Z","desc":"3.16","publishedAt":"2016-03-16T11:24:01.505Z","source":"chrome","type":"福利","url":"http://ww3.sinaimg.cn/large/610dc034gw1f1yj0vc3ntj20e60jc0ua.jpg","used":true,"who":"代码家"},{"_id":"56e764116776592d80511280","_ns":"ganhuo","createdAt":"2016-03-15T09:23:29.580Z","desc":"3.15","publishedAt":"2016-03-15T11:45:57.350Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/7a8aed7bjw1f1xad7meu2j20dw0ku0vj.jpg","used":true,"who":"张涵宇"},{"_id":"56e619a46776591744cf05c0","_ns":"ganhuo","createdAt":"2016-03-14T09:53:40.126Z","desc":"3.14","publishedAt":"2016-03-14T11:55:19.66Z","source":"chrome","type":"福利","url":"http://ww1.sinaimg.cn/large/7a8aed7bjw1f1w5m7c9knj20go0p0ae4.jpg","used":true,"who":"张涵宇"},{"_id":"56e220ca67765966681b3a23","_ns":"ganhuo","createdAt":"2016-03-11T09:35:06.879Z","desc":"3.11--一周年快乐!!!","publishedAt":"2016-03-11T12:37:20.4Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/7a8aed7bjw1f1so7l2u60j20zk1cy7g9.jpg","used":true,"who":"张涵宇"},{"_id":"56e0f0e86776596669cc2511","_ns":"ganhuo","createdAt":"2016-03-10T11:58:32.298Z","desc":"3.10","publishedAt":"2016-03-10T12:54:31.68Z","source":"chrome","type":"福利","url":"http://ww4.sinaimg.cn/large/7a8aed7bjw1f1rmqzruylj20hs0qon14.jpg","used":true,"who":"张涵宇"},{"_id":"56df891167765947765e2ad1","_ns":"ganhuo","createdAt":"2016-03-09T10:23:13.778Z","desc":"3.9","publishedAt":"2016-03-09T12:06:26.401Z","source":"chrome","type":"福利","url":"http://ww2.sinaimg.cn/large/7a8aed7bjw1f1qed6rs61j20ss0zkgrt.jpg","used":true,"who":"张涵宇"},{"_id":"56de2b1b6776592b6192bf46","_ns":"ganhuo","createdAt":"2016-03-08T09:30:03.578Z","desc":"3.8","publishedAt":"2016-03-08T12:55:59.161Z","source":"chrome","type":"福利","url":"http://ww3.sinaimg.cn/large/7a8aed7bjw1f1p77v97xpj20k00zkgpw.jpg","used":true,"who":"张涵宇"},{"_id":"56dd06b56776592b6246e979","_ns":"ganhuo","createdAt":"2016-03-07T12:42:29.664Z","desc":"3.7","publishedAt":"2016-03-07T12:49:24.470Z","source":"chrome","type":"福利","url":"http://ww1.sinaimg.cn/large/7a8aed7bjw1f1o75j517xj20u018iqnf.jpg","used":true,"who":"张涵宇"}]
*/
private boolean error;
@SerializedName("results")
private List<Girl> girls;
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public List<Girl> getGirls() {
return girls;
}
public void setGirls(List<Girl> girls) {
this.girls = girls;
}
}
是不是很简单而且很优雅
当然Retrofit的内部实现更优雅使用了很多设计模式这里推荐一位大神的文章
下面在说一下Okhttp的拦截器Interceptor 这真的是一个用起来非常爽的东西实现起来也非常简单
上代码
public class OkhttpInterceptor implements Interceptor {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
//取到当前请求的Requset
Request oldRequest = chain.request();
//取到请求的URL ,对你的URL进行修改,比如拼接一个UID什么的
//也可以使用addQueryParameter拼接参数
String url = oldRequest.url().toString()+"?="+uid;
Request newRequest = oldRequest.newBuilder()
.method(oldRequest.method(), oldRequest.body())
.url(url)
.build();
return chain.proceed(newRequest); }
}
当然你也可以增加请求参数
HttpUrl.Builder urlBuilder = oldRequest.url()newBuilder()
.scheme(oldRequest.url().scheme()) .addQueryParameter("key", "value")
只需要把url里的参数改为urlBuilder就行了
当然具体的业务需求也会遇到一些问题比如当我们的后台用的是https的时候,需要用到自签名证书,而OKhttp3已经没有了setCertificates设置自签名证书时怎么办,没关系我们还有万能的反射呢,下面我们就利用反射把https给过滤掉
SSLContext sc = null;
try {
sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { }
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws java.security.cert.CertificateException { }
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null; } }
},
new SecureRandom());
} catch (Exception e) {
e.printStackTrace();
}
HostnameVerifier hv1 = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}};
String workerClassName = "okhttp3.OkHttpClient";
try {
sClient = new OkHttpClient.Builder().build();
Class workerClass = Class.forName(workerClassName);
Field hostnameVerifier = workerClass.getDeclaredField("hostnameVerifier"); hostnameVerifier.setAccessible(true);
hostnameVerifier.set(sClient, hv1);
Field sslSocketFactory = workerClass.getDeclaredField("sslSocketFactory"); sslSocketFactory.setAccessible(true);
sslSocketFactory.set(sClient, sc.getSocketFactory());
} catch (Exception e) {
e.printStackTrace();
}
这个反射只是用在忽略https上,现在国内主流还是http,一般是用不上的,拦截器的话要debug看看清楚,你可以在http执行请求之前做一些操作,比如加一些请求参数或者是判断什么的。
参考链接
30分钟上手最火android网络请求框架Retrofit - 简书
快速Android开发系列网络篇之Retrofit - AngelDevil - 博客园
Retrofit2.0
我在stackoverflow回答的关于Retrofit2.0的相关问题
Retrofit学习入门的更多相关文章
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- C# BackgroundWorker组件学习入门介绍
C# BackgroundWorker组件学习入门介绍 一个程序中需要进行大量的运算,并且需要在运算过程中支持用户一定的交互,为了获得更好的用户体验,使用BackgroundWorker来完成这一功能 ...
- 给深度学习入门者的Python快速教程 - 番外篇之Python-OpenCV
这次博客园的排版彻底残了..高清版请移步: https://zhuanlan.zhihu.com/p/24425116 本篇是前面两篇教程: 给深度学习入门者的Python快速教程 - 基础篇 给深度 ...
- 给深度学习入门者的Python快速教程 - numpy和Matplotlib篇
始终无法有效把word排版好的粘贴过来,排版更佳版本请见知乎文章: https://zhuanlan.zhihu.com/p/24309547 实在搞不定博客园的排版,排版更佳的版本在: 给深度学习入 ...
- UML学习入门就这一篇文章
1.1 UML基础知识扫盲 UML这三个字母的全称是Unified Modeling Language,直接翻译就是统一建模语言,简单地说就是一种有特殊用途的语言. 你可能会问:这明明是一种图形,为什 ...
- Stanford Parser学习入门(2)-命令行运行
在Stanford parser目录中已经定义了一部分命令行工具以及图形界面,本文将介绍如何在windows使用这些工具进行语法分析,Linux下也有shell可以使用. 关于如何搭建环境请参考上一篇 ...
- Python学习入门基础教程(learning Python)--5.6 Python读文件操作高级
前文5.2节和5.4节分别就Python下读文件操作做了基础性讲述和提升性介绍,但是仍有些问题,比如在5.4节里涉及到一个多次读文件的问题,实际上我们还没有完全阐述完毕,下面这个图片的问题在哪呢? 问 ...
- 深度学习入门实战(二)-用TensorFlow训练线性回归
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者 :董超 上一篇文章我们介绍了 MxNet 的安装,但 MxNet 有个缺点,那就是文档不太全,用起来可能 ...
- Shell脚本编程学习入门 02
Shell脚本编程学习入门是本文要介绍的内容,我们可以使用任意一种文字编辑器,比如gedit.kedit.emacs.vi等来编写shell脚本,它必须以如下行开始(必须放在文件的第一行): #! ...
随机推荐
- Redis学习笔记五:独立功能之事务
Redis 事务提供了一种将多个命令请求打包,然后一次性.按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断,会将事务中的所以命令都执行完毕才去处理其他客户端的命令请求. 事务的实现 事务 ...
- JAVA操作ORACLE数据库的存储过程
一.任务提出 JAVA操作oracle11g存储过程实验需要完成以下几个实例: 1.调用没有返回参数的过程(插入记录.更新记录) 2.有返回参数的过程 3.返回列表的过程 4.返回带分页的列表的过程. ...
- JAVA Io 缓冲输入输出流
java中提供带缓冲的输入输出流.在打开文件进行写入或读取操作时,都会加上缓冲,提高了IO读写性能. 1. BufferedInputStream 缓冲输入流 2. BufferedOutputStr ...
- Jrebel是一套开发环境,用来实现热部署
http://truemylife.iteye.com/blog/1140921 背景与愿景:开发环境下,tomcat对热布署的支持还不够全面,致使开发人员浪费大量时间在重起服务上.为了提高开发效率, ...
- iOS开发——UI基础-Xcode资源拷贝
#1.拷贝资源的时候选择的copy的含义: 是否要将资源拷贝一份到项目中, 如果不勾选就代表着不拷贝, 那么原来的资源不见了, 项目中的也不能用了 注意: 1.虽然项目中的图片和外部的图片是同一张图片 ...
- BZOJ4411——[Usaco2016 Feb]Load balancing
1.题意: 给出N个平面上的点.保证每一个点的坐标都是正奇数. 你要在平面上画两条线,一条是x=a,一条是y=b,且a和b都是偶数. 直线将平面划成4个部分,要求包含点数最多的那个部分点数最少. 2. ...
- Android--多线程之Handler
前言 Android的消息传递机制是另外一种形式的“事件处理”,这种机制主要是为了解决Android应用中多线程的问题,在Android中不允许Activity新启动的线程访问该Activity里的U ...
- iOS软件版本更新思路
iOS软件更新思路 需要更新版本数组 needUpdateVersions{1.2.61.2.8} 历史版本数组 historyUpdateVersions1.2.41.2.51.2.6 更新数据库1 ...
- 一个按比特位拷贝数据的函数copybits
一个按比特位拷贝数据的函数 没有进行特别的优化.其实还可以在拷贝源开始位置和目标开始位置是2的整数倍位置的时候进行优化. 说明 这个函数用于从src数组首地址跳过sbb个字节,又跳过ssb个比特位,拷 ...
- 5.6---交换整数的奇数位和偶数位(CC150)
这道题要利用101010来&. 如下答案: public class Exchange { public int exchangeOddEven(int x) { // write code ...