Retrofit 最简单的快速入门及封装
- Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,OkHttp现在已经得到Google官方认可,大量的app都采用OkHttp做网络请求
- Retrofit也就成了最火的网络请求框架之一,想着来研究一下Retrofit了…先看了看官方文档,发现各种坑,Retrofit是结合着注解来做的,思路新颖,但是不符合大部分开发程序员的思维习惯,一开始使用的时候,不太适应…附上官方文档的介绍
Retrofit turns your HTTP API into a Java interface.public interface GitHubService {@GET("users/{user}/repos")Call<List<Repo>> listRepos(@Path("user") String user);
}
The Retrofit class generates an implementation of the GitHubService interface.Retrofit retrofit = new Retrofit.Builder().baseUrl("https://api.github.com/").build();GitHubService service = retrofit.create(GitHubService.class);
Each Call from the created GitHubService can make a synchronous or asynchronous HTTP request to the remote webserver.Call<List<Repo>> repos = service.listRepos("octocat");
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
快速入门,从Hello 百度走起
- 想快速入门Retrofit,我们最简单的想法是能请求一下www.baidu.com,然后将信息打印一下,但是发现在Retrofit入门的时候,访问www.baidu.com竟然成了奢求…,大部分的文章都是模仿着官方文档来写的…
- 先一起来写一个访问百度,展示数据的示例
- 第一步:gradle文件中进行配置
compile 'com.squareup.retrofit2:retrofit:2.0.0-beta2'compile 'com.squareup.retrofit2:adapter-rxjava:2.0.0-beta2'compile 'com.squareup.retrofit2:converter-scalars:2.0.0'
- 1
- 2
- 3
- 第二步:定义一个接口,接口中使用注解注明请求方式,及对应的请求路径
public interface DataService {//指定get请求方式 指定路径 有时候路径除了baseUrl还有一部分比如 http://write.blog.csdn.net/mdeditor //http://write.blog.csdn.net/ 一般是baseUrl//而 mdeditor是相对路径的@GETCall<String> baidu(@Url String url);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 第二步:进行请求
//创建Retrofit对象Retrofit retrofit = new Retrofit.Builder()//指定baseurl,这里有坑,最后后缀出带着“/” .baseUrl("http://www.baidu.com/")//设置内容格式,这种对应的数据返回值是String类型.addConverterFactory(ScalarsConverterFactory.create())//定义client类型.client(new OkHttpClient())//创建.build();//通过retrofit和定义的有网络访问方法的接口关联DataService dataService = retrofit.create(DataService.class);//在这里又重新设定了一下baidu的地址,是因为Retrofit要求传入具体,如果是决定路径的话,路径会将baseUrl覆盖掉Call<String> baidu = dataService.baidu("http://wwww.baidu.com");//执行异步请求baidu.enqueue(new Callback<String>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {Toast.makeText(MainActivity.this, response.body(), Toast.LENGTH_SHORT).show();}@Overridepublic void onFailure(Call<String> call, Throwable t) {}});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 通过上述代码,咱们就可以完整的看见百度的html界面了,算是对Retrofit做一个入门
其他请求-QQ吉凶测试
第三方网站聚合数据上的测试地址,key有可能过期,大家测的时候可以自己申请key 官网 https://www.juhe.cn
http://japi.juhe.cn/qqevaluate/qq?key=96efc220a4196fafdfade0c9d1e897ac&qq=295424589
返回数据内容
{"error_code":0,"reason":"success","result":{"data":{"conclusion":"[大吉+官运+财运+才艺]如龙得云,青云直上,智谋奋进,才略奏功","analysis":"欲望难足希望高,计谋成功财力豪,猜疑嫉妒性自改,如龙乘云势运开。智能超人贯彻大志,富贵无比,不甘寂寞,叱吒风云之大吉数,但容易发生牢骚及贪心、欲望太多而永不知足,为其缺点。切忌沉迷投机,可免贻误前程。"}}}
- 1
对于Retrofit可以直接生成对应的json
第一步:生成对应的Bean,例如 QQData
第二步:在接口中定义请求方法
- GET请求
- 请求相对路径
- 参数内容
- Call代表是一个请求
public interface DataService {@GET("/qqevaluate/qq")Call<QQData> getQQData(@Query("key") String appkey, @Query("qq") String qq);}
- 1
- 2
- 3
- 4
- 5
- 第三步:开始请求
Retrofit retrofit = new Retrofit.Builder().baseUrl("http://japi.juhe.cn").addConverterFactory(GsonConverterFactory.create()).build();DataService dataService = retrofit.create(DataService.class);final Call<QQData> qqData = dataService.getQQData("96efc220a4196fafdfade0c9d1e897ac", "11111111");qqData.enqueue(new Callback<QQData>() {@Overridepublic void onResponse(Response<QQData> response, Retrofit retrofit) {String reason = response.body().getReason();Toast.makeText(MainActivity.this, response.body().getReason(), Toast.LENGTH_SHORT).show();}@Overridepublic void onFailure(Throwable t) {Toast.makeText(MainActivity.this, "--" + t.getMessage().toString(), Toast.LENGTH_SHORT).show();}});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 以上是Retrofit的简单应用,当然对于Retrofit还有一些其他的方式
///https://zhidao.baidu.com/daily/view//路径拼接的形式,v代表是其中的一个参数,可以在这个位置进行拼接@GET("daily/{v}")Call<String> baiduzhidao(@Path("v") String v);//在注解中指定路径,定义相对应的参数的集合@GET("qqevaluate/qq")Call<QQData> getQQDataMap(@QueryMap Map<String,String> map);//对应Post请求,参数的注解是@Field@POST("qqevaluate/qq")Call<QQData> postQQData(@Field("key") String key,@Field("qq") String qq);//必须指定进行表单编码@FormUrlEncoded//指定参数是map形式 @FieldMap@POST("qqevaluate/qq")Call<QQData> postQQDataMap(@FieldMap Map<String,String> map);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
自己封装一个简易的Retrofit请求
对于Retrofit,我们发现确实有一些特色,请求也比较简单,但是,当在一个大的项目中,不可能每一请求都到接口中声明一下。所以有必要进行简易的封装
封装一个简易的请求接口
public interface ProjectAPI {//http://www.baidu.com/aaa?key=123&qq=aaa@GETCall<String> getMethod(@Url String url);@FormUrlEncoded@POSTCall<String> postMethod(@Url String url, @FieldMap Map<String,String> map);}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 定义一个网络请求的管理类,需要注意的是这里的baseUrl创建了,如果url是在其基础上的,就会进行相应的拼接,如果url是全路径,就会覆盖掉baseUrl
public class HttpManger {/*** @param baseUrl 基础Url* @param url 附加Url* @param callback 添加请求回调,这里直接使用的是Retrofit自身的回调接口*/public static void getMethod(String baseUrl, String url, final Callback<String> callback) {Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).addConverterFactory(ScalarsConverterFactory.create()).build();ProjectAPI projectAPI = retrofit.create(ProjectAPI.class);Call<String> call = projectAPI.getMethod(url);call.enqueue(new Callback<String>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {//调用回调callback.onResponse(call, response);}@Overridepublic void onFailure(Call<String> call, Throwable t) {//调用回调callback.onFailure(call, t);}});}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- Post请求方式的封装,参数通过map集合的方式进行传递
public static void postMethod(String baseUrl, String url, Map<String, String> map, final Callback<String> callback) {//指定客户端Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(httpClient).addConverterFactory(ScalarsConverterFactory.create()).build();ProjectAPI projectAPI = retrofit.create(ProjectAPI.class);Call<String> call = projectAPI.postMethod(url, map);call.enqueue(new Callback<String>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {callback.onResponse(call, response);}@Overridepublic void onFailure(Call<String> call, Throwable t) {callback.onFailure(call, t);}});}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 方法调用-Get方式调用,这里的key大家可以替换一下
HttpManger.getMethod("http://japi.juhe.cn/", "http://japi.juhe.cn/qqevaluate/qq?key=96efc220a4196fafdfade0c9d1e897ac&qq=295424589", new Callback<String>() {@Overridepublic void onResponse(Call<String> call, Response<String> response) {Toast.makeText(MainActivity.this, "--"+response.body(), Toast.LENGTH_SHORT).show();}@Overridepublic void onFailure(Call<String> call, Throwable t) {Toast.makeText(MainActivity.this, "--"+t.getMessage(), Toast.LENGTH_SHORT).show();}});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- POST方式调用
Map<String, String> map=new HashMap<>();map.put("key","96efc220a4196fafdfade0c9d1e897ac");map.put("qq","111111111");HttpManger.postMethod(false,false,"http://japi.juhe.cn/","qqevaluate/qq",map,new Callback<String>(){@Overridepublic void onResponse(Call<String> call, Response<String> response) {Toast.makeText(MainActivity.this, "--"+response.body(), Toast.LENGTH_SHORT).show();}@Overridepublic void onFailure(Call<String> call, Throwable t) {Toast.makeText(MainActivity.this, "--"+t.getMessage(), Toast.LENGTH_SHORT).show();}});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 正好最近做到了Cookie的应用,在本讲解中进行一下讲解
- 创建一个保存Cookie的拦截器,用于获取服务器打给客户端的Cookie信息
public class SaveCookiesInterceptor implements Interceptor {@Overridepublic okhttp3.Response intercept(Chain chain) throws IOException {//获取到响应Response originalResponse = chain.proceed(chain.request());//进行Cookie获取以及字符串的拼接,Cookie在使用的过程要//根据具体公司来定if (!originalResponse.headers("Set-Cookie").isEmpty()) {//根据Set-Cookie获取出的信息for (String header : originalResponse.headers("Set-Cookie")) {Log.i("AAAA----","=="+header+"==");String cookie = header.substring(0, header.indexOf(";") + 1);stringBuilder.append(cookie);}}//拼接时完成后将该Cookie保存到 SharedPreferences中SharedPreferencesUtils.saveString(MyApplication.context,"cookie",stringBuilder.toString());return originalResponse;}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 创建读取Cookie的拦截器
public class ReadCookiesInterceptor implements Interceptor {@Overridepublic okhttp3.Response intercept(Chain chain) throws IOException {Request.Builder builder = chain.request().newBuilder();String cookie = SharedPreferencesUtils.getString(MyApplication.context, "cookie", "");//将cookie添加到请求头中builder.addHeader("Cookie", cookie);return chain.proceed(builder.build());}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 在HttpManager中指定拦截器的使用,但是并不是所有的请求都要保存cookie或者所有的请求都要读取cookie,所以我们添加一个判断
/*** * @param isReadCookie 是否要读取cookie* @param isSaveCookie 是否要保存cookie* @param baseUrl 基础Url* @param url 要拼接的url * @param map 参数集合* @param callback 请求回调*/public static void postMethod(boolean isReadCookie, boolean isSaveCookie, String baseUrl, String url, Map<String, String> map, final Callback<String> callback) {OkHttpClient httpClient = null;if (isReadCookie && !isSaveCookie) {httpClient = new OkHttpClient.Builder().addInterceptor(new ReadCookiesInterceptor()).build();Log.i("AAA","只读不写");}if (isSaveCookie && !isReadCookie) {httpClient = new OkHttpClient.Builder().addInterceptor(new SaveCookiesInterceptor()).build();Log.i("AAA","只写不读");}if (isSaveCookie && isReadCookie) {httpClient = new OkHttpClient.Builder().addInterceptor(new SaveCookiesInterceptor()).addInterceptor(new ReadCookiesInterceptor()).build();Log.i("AAA","又写又读");} if (!isSaveCookie && !isReadCookie){httpClient = new OkHttpClient.Builder().build();Log.i("AAA","不写不读");}//指定客户端Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(httpClient).addConverterFactory(ScalarsConverterFactory.create()).build();
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 好了,暂时写到这里,以上就是对Retrofit的一个简易封装,当然网上也有一些大神对Retrofit进行了封装。
Retrofit 最简单的快速入门及封装相关推荐
- Retrofit 最简单的快速入门及自己封装
简单介绍及官方文档的坑 官方文档 http://square.github.io/retrofit/ Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底 ...
- el-admin框架简单解析-快速入门(前端部分)
目录 el-admin 简单了解 使用框架的四大步 el-admin前端部分解析 前端Vue目录结构 Layout 布局 mixins 混入模式 router 路由 store 状态管理 utils ...
- ccs一个简单的快速入门
文章目录 1. 什么是css 网址 1.1 什么是css 1.2 发展史. 2.快速入门 选择器 1.三大基本选择器 2. 层次选择器 3.结构伪类选择器 4. 属性选择器(常用) 样式 三大样式 3 ...
- Retrofit+RxJava简单使用(入门专用= - =)
首先老规矩加入所需要的依赖 这里要根据自己的gradle进行适配的依赖,否则会引起不必要的错误!!! 另外Retrofit是基于Okhttp请求,需要进行网络请求,所以这里我们还要加入网络权限:第一条 ...
- Freemarker简单概述及其数据类型的简单学习—快速入门(一)
FreeMarker的主要学习内容 一.FreeMarker概述 FreeMarker中文官方手册(可结合学习)http://freemarker.foofun.cn/ FreeMarker学习笔记源 ...
- EventBus3.0简单使用快速入门
加入引用 implementation 'org.greenrobot:eventbus:3.0.0' 自定义一个事件类 public class EventBusMessage {public St ...
- EasyX简单绘图快速入门
众所周知EasyX是一款在C++环境上运行的图形交互库,如果你觉得C\C++好无聊,你可以玩玩这个,官网也有下载链接,我这里有15年的版本,但是无法发链接,如果想要的可以在评论区留言或者私信我 在De ...
- 10、JSP快速入门
目录 1.jsp简述 2.JSP快速入门 2.1.搭建环境 2.2.导入JSP页面 2.3.编写代码 2.4.启动测试 3.JSP原理 4.JSP脚本 4.1.JSP脚本的分类 4.2.案例 4.2. ...
- Shiro第一个程序:官方快速入门程序Qucickstart详解教程
目录 一.下载解压 二.第一个Shiro程序 1. 导入依赖 2. 配置shiro配置文件 3. Quickstart.java 4. 启动测试 三.shiro.ini分析 四.Quickstart. ...
最新文章
- 【FFmpeg】RTSP、RTMP相关命令及开源项目
- mysql用in报错_Mysql子查询IN中使用LIMIT
- swift变量和函数
- P6222-「P6156 简单题」加强版【莫比乌斯反演】
- 删除linux 软raid0,配置Linux软RAID0
- CFI/CFG 安全防护原理详解(ROP攻击、DOP攻击、插装检测)
- 花呗将全面接入央行征信系统,拒绝接入将无法使用 网友:还好我不买房
- unity3D---鼠标、键盘输入
- linux网站配置文件.htaccess伪静态转换到IIS web.config中
- ArcGIS Python工具箱集成第三方模块的解决办法
- Qunee for HTML5图形组件
- 自定义Android Switch控件
- 如何让ARM板开机启动Qt
- 计算机主板维修试卷,计算机主板维修试卷.doc
- ADF11g-041:禁止或允许其它网站添加ADF页面到iframe中
- 微信 小程序 python 商城_微信小程序——商城篇
- Winform(C#) 国内开源美化控件主题库2:花木兰控件库
- 市场调研你所不知道的几个关键点
- php background,background什么意思
- Smart3D输出Orthophoto(正射影像)和DSM(数字地表模型)+ArcGIS拼接TIFF/GeoTIFF文件
热门文章
- 淘宝详情原数据API接口调用示例
- 串口485接法图_终于有人把常用的三种通讯方式:RS485、RS232、RS422讲明白了
- 狂奔的蔚来:上市背后的必然与隐忧
- 【Java百炼成神】魂圣初入Java ——安装JDK、环境变量、HelloWorld
- TPS65983ACZQZR USB Type-C 控制器和553SDCGI8时钟缓冲器、SLB9665TT2.0应用说明
- python遍历argparse的parse_args()
- 为什么vscode很多人用?
- transferTo 方法
- 大跨度桥梁类毕业论文文献包含哪些?
- 思维探索者:我们需要演绎与归纳