Android开发 retrofit入门讲解
前言
retrofit基于okhttp封装的网络请求框架,网络请求的工作本质上是 OkHttp 完成,而 retrofit 仅负责网络请求接口的封装.如果你不了解OKhttp建议你还是先了解它在来学习使用retrofit,传送门:Android 开发 框架系列 OkHttp使用详解
Retrofit优势,就是简洁易用,解耦,扩展性强,可搭配多种Json解析框架(例如Gson),另外还支持RxJava.但是,这篇博客不讲解RxJava配合使用的部分,与RxJava的配合使用将在另外一篇博客中讲解.
另外retrofit已经是封装的非常好了,已经最大程度上的匹配各种使用情况,所以不建议多此一举的再次封装retrofit(最多封装retrofit的单例). 再次封装不会看起来很帅也不会让你很牛逼. 只会让你看起来更蠢.把已经很拓展很解耦的实现全部破坏.
Github地址
https://github.com/square/retrofit
依赖
如果你不需要使用RxJava模式,那么你只需要依赖下面2个:
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
gson是用来解析的Json数据使用的(个人偏爱Gson),retrofit也支持其他解析工具比如fastJson
简单的Demo(异步请求)
老规矩按思维顺序讲解demo
1.创建Retrofit请求基础配置
Retrofit配置好后,可以全局使用这一个Retrofit用来请求网络(所以你可以实现单例以全局使用),当然下面的代码只是demo:
private Retrofit mRetrofit;
private void initHttpBase(){
mRetrofit = new Retrofit.Builder()
.baseUrl("http://doclever.cn:8090/mock/5c3c6da33dce46264b24452b/")//base的网络地址 baseUrl不能为空,且强制要求必需以 / 斜杠结尾
.addConverterFactory(GsonConverterFactory.create())//使用Gson解析
.callbackExecutor(Executors.newSingleThreadExecutor())//使用单独的线程处理 (这很重要,一般网络请求如果不设置可能不会报错,但是如果是下载文件就会报错)
.build();
}
注意! base的网络地址 baseUrl不能为空,且强制要求必需以 / 斜杠结尾
2.创建数据返回后的Bean类
public class LoginBean {
private int code;
private String message;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
2.创建一个网络请求接口
public interface HttpList {
@FormUrlEncoded //注解表示from表单 还有@Multipart 表单可供使用 当然你也可以不添加
@POST("test/login_test") //网络请求路径
Call<LoginBean> login(@Field("number") String number, @Field("password") String password); //@Field("number") 为post值的的key
}
注意,这是一个接口类. LoginBean则是数据返回后的Bean类(Retrofit会自动使用导入的Gson解析)
注意! @POST("test/login_test") 这路径最前面不能加斜杠 / ,否则它会自动裁剪路径,这样会导致你的路径错误
3.请求网络
private void postHttp(){
HttpList httpList = mRetrofit.create(HttpList.class);
Call<LoginBean> call = httpList.login("181234123", "123456");
call.enqueue(new Callback<LoginBean>() {
@Override
public void onResponse(Call<LoginBean> call, Response<LoginBean> response) {
LoginBean bean = response.body();
Log.e(TAG, "onResponse: code="+bean.getCode());
Log.e(TAG, "onResponse: message="+bean.getMessage());
}
@Override
public void onFailure(Call<LoginBean> call, Throwable t) {
Log.e(TAG, "onFailure: 网络请求失败="+t.getMessage());
}
});
}
这样,我们就完成了一个网络请求.是不是特别简单
同步请求
private void postHttp2() {
HttpList httpList = mRetrofit.create(HttpList.class);
final Call<LoginBean> call = httpList.login("181234123", "123456");
new Thread(new Runnable() { //Android主线程不能操作网络请求,所以new一个线程来操作
@Override
public void run() {
try {
Response<LoginBean> response = call.execute();//同步请求网络
LoginBean bean = response.body();
Log.e(TAG, "onResponse: code=" + bean.getCode());
Log.e(TAG, "onResponse: message=" + bean.getMessage());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
取消网络请求
public void cancelHttp(){
HttpList httpList = mRetrofit.create(HttpList.class);
//这里贴这部分代码是告诉call是哪里来的,关键点就是这个call,当然你也可以从回调里获取
mCall = httpList.login("181234123", "123456");
mCall.cancel(); //取消请求
}
如何添加Header头
以固定数据的形式添加头信息
public interface HttpList {
@Headers({"content1:one","content2:two"})
@POST("test/logout_test")
Call<LoginBean> logout1();
}
以非固定数据的形式添加头信息
public interface HttpList {
@POST("test/logout_test")
Call<LoginBean> logout2(@Header("content") String content);
}
Body配置
Body一般有4个种类
- application/x-www-form-urlencoded 表单数据
- multipart/form-data 表单文件上传
- application/json 序列化JSON数据
- text/xml XML数据
框架直接提供的2个Body
public interface HttpList {
@FormUrlEncoded //application/x-www-form-urlencoded 表单body
@POST("test/login_test")
Call<LoginBean> login2(@Field("number") String number, @Field("password") String password);
@Multipart //multipart/form-data 此body支持文件上传与下载
@POST("test/login_test")
Call<LoginBean> login3(@Field("number") String number, @Field("password") String password);
}
自定义Body
其他2个就需要自定义创建了,下面举例Json Body的创建:
/**
*
* @param string 直接导入需要发送给服务器的JSON的String值
* @return
*/
public static RequestBody getRequestBody(String string) {
return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), string);
}
在接口类参数需要设置为 @Body RequestBody requestBody
@POST("app/system/demo")
Observable<UpdateInfo> demo(@Body RequestBody requestBody);
添加配置的OkHttpClient(主要使用请求超时/拦截器等功能)
上面说了retrofit是基于Okhttp开发的网络请求框架,所以它有一部分的功能依然需要使用Okhttp的方式来配置比如请求超时时间/设置拦截器等等,下面就展示一下如何添加
private void initHttpBase2() {
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.retryOnConnectionFailure(false) //在连接失败时重试
.callTimeout(30, TimeUnit.SECONDS) //呼叫超时,设置此参数为整体流程请求的超时时间
.connectTimeout(20,TimeUnit.SECONDS)//连接超时
.readTimeout(20,TimeUnit.SECONDS)//读取超时
.writeTimeout(20,TimeUnit.SECONDS)//写入超时
// .callTimeout()//呼叫超时,设置此参数为整体流程请求的超时时间
// .addInterceptor() //设置拦截器
// .authenticator() //设置认证器
// .proxy()//设置代理
.build();
mRetrofit = new Retrofit.Builder()
.client(okHttpClient)
.baseUrl("http://doclever.cn:8090/mock/5c3c6da33dce46264b24452b/")//base的网络地址
.addConverterFactory(GsonConverterFactory.create())//使用Gson解析
.callbackExecutor(Executors.newSingleThreadExecutor())
.build();
}
部分路径动态的BaseUrl
@POST("/article/query/{page}/json")
@FormUrlEncoded
Observable<DataResponse<Article>> getSearchArticles(@Path("page") int page, @Field("k") String k);
实现Url路径传参数
@Query 有值的查询名称
@GET("app/data")
Call<Result> getData(@Query("id") String id);
@GET("app/data")
Call<Result> getData(@Query("id") String... id);
@QueryName 只有值没有key的传参
@GET("app/data")
Call<Resul> getData(@QueryName String id);
@GET("app/data")
Call<Resul> getData(@QueryName String... id);
@QueryMap 用哈希集合传值
@GET("app/data")
Call<Result> getData(@QueryMap Map<String,String> map);
end
Android开发 retrofit入门讲解的更多相关文章
- Android开发 retrofit入门讲解 (RxJava模式)
前言 retrofit除了正常使用以外,还支持RxJava的模式来使用,此篇博客讲解如何使用RxJava模式下的retrofit 依赖 implementation 'com.squareup.ret ...
- 学Android开发,入门语言java知识点
学Android开发,入门语言java知识点 Android是一种以Linux为基础的开源码操作系统,主要使用于便携设备,而linux是用c语言和少量汇编语言写成的,如果你想研究Android,就去学 ...
- 「Android 开发」入门笔记
「Android 开发」入门笔记(界面编程篇) ------每日摘要------ DAY-1: 学习笔记: Android应用结构分析 界面编程与视图(View)组件 布局管理器 问题整理: Andr ...
- 使用Ant搭建Android开发环境入门
使用Ant搭建Android开发环境入门 使用Ant搭建Android开发环境,建立android项目 配置Ant环境 下载Ant:http://ant.apache.org/bindownloa ...
- android 开发从入门到精通
Android-Tips This is an awesome list of tips for android. If you are a beginner, this list will be t ...
- Android开发快速入门(环境配置、Android Studio安装)
Android是一种激动人心的开源移动平台,它像手机一样无处不在,得到了Google以及其他一些开放手机联盟成员(如三星.HTC.中国移动.Verizon和AT&T等)的支持,因而不能不加以学 ...
- Android开发 retrofit下载与上传
前言 此博客只讲解retrofit下载与上传的使用,其实与其说是retrofit的下载与上传还不如说,依然是Okhttp的下载与上传.如果你需要了解retrofit入门请查看这篇博客(此博客不在详细讲 ...
- Java ME之Android开发从入门到精通
1. 搭建Android开发环境 方式一:使用ADT插件安装 ADT插件的下载与安装,ADT插件获取网址:http://www.androiddevtools.cn/ 下载好的ADT插件如图所示: 在 ...
- Android开发 MediaPlayer入门_播放本地视频
前言 MediaPlayer,可以播放视频/音频,并且它支持本地和网络文件的播放.本片博客作为入门教程,先以最通俗的方式解释播放文件本地视频.(如果你嫌MediaPlayer还是太麻烦可以试试选择Vi ...
随机推荐
- Apache POI环境设置
本章将指导完成Apache POI在Windows和Linux系统为基础的设置过程. Apache POI可以轻松地安装和集成,下面没有任何复杂的设置过程,通过几个简单步骤,目前Java环境,用户管理 ...
- 调用phone库,查询手机号码归属地(4)
需要安装pymysql,phone库 #!/usr/bin/python # -*- coding: utf-8 -*- import sys, pymysql, logging, phone fro ...
- 不在B中的A的子串数量 HDU - 4416 (后缀自动机模板题目)
题目: 给定一个字符串a,又给定一系列b字符串,求字符串a的子串不在b中出现的个数. 题解: 先将所有的查询串放入后缀自动机(每次将sam.last=1)(算出所有子串个数) 然后将母串放入后缀自动机 ...
- 监控数据库SqlServer
监控数据库的连接数select COUNT( * ) from master.dbo.sysprocesses select COUNT( * ) from master.dbo.sysprocess ...
- 使用Docker快速部署ELK分析Nginx日志实践
原文:使用Docker快速部署ELK分析Nginx日志实践 一.背景 笔者所在项目组的项目由多个子项目所组成,每一个子项目都存在一定的日志,有时候想排查一些问题,需要到各个地方去查看,极为不方便,此前 ...
- Vue+element ui table 导出到excel
需求: Vue+element UI table下的根据搜索条件导出当前所有数据 参考: https://blog.csdn.net/u010427666/article/details/792081 ...
- struts2类型转换1
概述 从一个 HTML 表单到一个 Action 对象, 类型转换是从字符串到非字符串. HTTP 没有 “类型” 的概念. 每一项表单输入只可能是一个字符串或一个字符串数组. 在服务器端, 必须把 ...
- 带你彻底理解RSA算法原理,很简单的
1. 什么是RSA RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法. 在了解RSA算法之前,先熟悉下几个术语 根据密钥的使用方法,可以将密码分为 对称密码 和 公钥密码 对称 ...
- word embedding 精要整理
word embedding 具体含义:词的实数向量化表示,可以通过向量相似性度量语义相似性,相似性原理是上下文的一致性 Embedding在数学上表示一个maping, f: X -> Y, ...
- vuex之module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象.当应用变得非常复杂时,store 对象就有可能变得相当臃肿. 为了解决以上问题,Vuex 允许我们将 store 分割成模块(module) ...