# 目录
* [集成文档](#集成文档)
* [配置权限](#配置权限)
* [Http 明文请求](#http-明文请求)
* [服务器配置](#服务器配置)
* [框架初始化](#框架初始化)
* [使用文档](#使用文档)
* [配置接口](#配置接口)
* [发起请求](#发起请求)
* [上传文件](#上传文件)
* [下载文件](#下载文件)
* [分区存储适配](#分区存储适配)
* [发起同步请求](#发起同步请求)
* [设置请求缓存](#设置请求缓存)
* [搭配协程使用](#搭配协程使用)
* [疑难解答](#疑难解答)
* [如何设置 Cookie](#如何设置-cookie)
* [如何添加或者删除全局参数](#如何添加或者删除全局参数)
* [如何动态添加全局的参数或者请求头](#如何动态添加全局的参数或者请求头)
* [如何在请求中忽略某个全局参数](#如何在请求中忽略某个全局参数)
* [如何获取服务器配置](#如何获取服务器配置)
* [如何修改接口的服务器配置](#如何修改接口的服务器配置)
* [如何配置多域名](#如何配置多域名)
* [如何修改参数的提交方式](#如何修改参数的提交方式)
* [如何对接口进行加密或者解密](#如何对接口进行加密或者解密)
* [如何忽略某个参数](#如何忽略某个参数)
* [如何传入请求头](#如何传入请求头)
* [如何传入动态的请求头](#如何传入动态的请求头)
* [如何重命名参数或者请求头的名称](#如何重命名参数或者请求头的名称)
* [如何上传文件](#如何上传文件)
* [如何上传文件列表](#如何上传文件列表)
* [如何设置超时重试](#如何设置超时重试)
* [如何设置请求超时时间](#如何设置请求超时时间)
* [如何设置不打印日志](#如何设置不打印日志)
* [如何修改日志打印策略](#如何修改日志打印策略)
* [如何取消已发起的请求](#如何取消已发起的请求)
* [如何延迟发起一个请求](#如何延迟发起一个请求)
* [如何对接口路径进行动态化拼接](#如何对接口路径进行动态化拼接)
* [如何动态化整个请求的 url](#如何动态化整个请求的-url)
* [Https 如何配置信任所有证书](#https-如何配置信任所有证书)
* [我不想一个接口写一个类怎么办](#我不想一个接口写一个类怎么办)
* [框架只能传入 LifecycleOwner 该怎么办](#框架只能传入-lifecycleowner-该怎么办)
* [如何在 ViewModel 中使用 EasyHttp 请求网络](#如何在-viewmodel-中使用-easyhttp-请求网络)
* [我想取消请求时显示的加载对话框该怎么办](#我想取消请求时显示的加载对话框该怎么办)
* [我想用 Json 数组作为参数进行上传该怎么办](#我想用-json-数组作为参数进行上传该怎么办)
* [接口参数的 Key 值是动态变化的该怎么办](#接口参数的-key-值是动态变化的该怎么办)
* [如何设置自定义的 UA 标识](#如何设置自定义的-ua-标识)
* [我想修改请求回调所在的线程该怎么办](#我想修改请求回调所在的线程该怎么办)
* [我想自定义一个 RequestBody 进行请求该怎么办](#我想自定义一个-requestbody-进行请求该怎么办)
* [我想自定义请求头中的 ContentType 该怎么做](#我想自定义请求头中的-contenttype-该怎么做)
* [我想自定义 Get 请求参数中的 key 和 value 该怎么做](#我想自定义-get-请求参数中的-key-和-value-该怎么做)
* [我想在 Post 请求中定义类似 Get 请求参数该怎么做](#我想在-post-请求中定义类似-get-请求参数该怎么做)
* [搭配 RxJava](#搭配-rxjava)
* [准备工作](#准备工作)
* [多个请求串行](#多个请求串行)
* [发起轮询请求](#发起轮询请求)
* [对返回的数据进行包装](#对返回的数据进行包装)
* [支持 Protobuf](#支持-protobuf)
* [准备工作](#准备工作)
* [请求体解析成 Protobuf](#请求体解析成-protobuf)
* [响应体解析支持 Protobuf](#响应体解析支持-protobuf)
# 集成文档
#### 配置权限
```xml
```
#### Http 明文请求
* **Android 9.0** 限制了明文流量的网络请求,非加密的流量请求都会被系统禁止掉。
* 如果当前应用的请求是 http 请求,而非 https,这样就会导系统禁止当前应用进行该请求,如果 WebView 的 url 用 http 协议,同样会出现加载失败,https 不受影响
* 在 res 下新建一个 xml 目录,然后创建一个名为:`network_security_config.xml` 文件 ,该文件内容如下
```xml
```
* 然后在 AndroidManifest.xml application 标签内应用上面的 xml 配置
```xml
```
#### 服务器配置
```java
public class RequestServer implements IRequestServer {
@NonNull
@Override
public String getHost() {
return "https://www.baidu.com/";
}
@NonNull
@Override
public IHttpBodyStrategy getBodyType() {
// 参数以 Json 格式提交(默认是表单)
return RequestBodyType.JSON;
}
}
```
#### 框架初始化
* 需要配置请求结果处理,具体封装可以参考 [RequestHandler](app/src/main/java/com/hjq/easy/demo/http/model/RequestHandler.java)
```java
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.build();
EasyConfig.with(okHttpClient)
// 是否打印日志
.setLogEnabled(BuildConfig.DEBUG)
// 设置服务器配置(必须设置)
.setServer(server)
// 设置请求处理策略(必须设置)
.setHandler(new RequestHandler())
// 设置请求缓存实现策略(非必须)
//.setCacheStrategy(new HttpCacheStrategy())
// 设置请求重试次数
.setRetryCount(3)
// 添加全局请求参数
//.addParam("token", "6666666")
// 添加全局请求头
//.addHeader("time", "20191030")
// 启用配置
.into();
```
* 上述是创建配置,更新配置可以使用
```java
EasyConfig.getInstance()
.addParam("token", data.getData().getToken());
```
# 使用文档
#### 配置接口
```java
public final class LoginApi implements IRequestApi {
@NonNull
@Override
public String getApi() {
return "user/login";
}
/** 用户名 */
private String userName;
/** 登录密码 */
private String password;
public LoginApi setUserName(String userName) {
this.userName = userName;
return this;
}
public LoginApi setPassword(String password) {
this.password = password;
return this;
}
}
```
* 可为这个类的字段加上一些注解
* @HttpHeader:标记这个字段是一个请求头参数
* @HttpIgnore:标记这个字段不会被发送给后台
* @HttpRename:重新定义这个字段发送给后台的参数或者请求头名称
* 可在这个类实现一些接口
* implements IRequestHost:实现这个接口之后可以重新指定这个请求的主机地址
* implements IRequestBodyType:实现这个接口之后可以重新指定这个请求体的提交方式
* implements IRequestCacheConfig:实现这个接口之后可以重新指定这个请求的缓存模式配置
* implements IRequestHttpClient:实现这个接口之后可以重新指定这个请求所用的 OkHttpClient 对象
* 字段作为请求参数的衡量标准
* 假设某个字段的属性值为空,那么这个字段将不会作为请求参数发送给后台
* 假设果某个字段类型是 String,属性值是空字符串,那么这个字段就会作为请求参数,如果是空对象则不会
* 假设某个字段类型是 int,因为基本数据类型没有空值,所以这个字段一定会作为请求参数,但是可以换成 Integer 对象来避免,因为 Integer 的默认值是 null
* 我举个栗子:[https://www.baidu.com/api/user/getInfo](https://www.baidu.com/),那么标准的写法就是
```java
public final class XxxApi implements IRequestServer, IRequestApi {
@NonNull
@Override
public String getHost() {
return "https://www.baidu.com/";
}
@NonNull
@Override
public String getApi() {
return "user/getInfo";
}
}
```
#### 发起请求
* 需要配置请求状态及生命周期处理,具体封装可以参考 [BaseActivity](app/src/main/java/com/hjq/easy/demo/BaseActivity.java)
```java
EasyHttp.post(this)
.api(new LoginApi()
.setUserName("Android 轮子哥")
.setPassword("123456"))
.request(new HttpCallbackProxy>(activity) {
@Override
public void onHttpSuccess(@NonNull HttpData data) {
toast("登录成功");
}
});
```
* 这里展示 post 用法,另外 EasyHttp 还支持 get、head、delete、put、patch 请求方式,这里不再过多演示
#### 上传文件
```java
public final class UpdateImageApi implements IRequestApi, IRequestBodyType {
@NonNull
@Override
public String getApi() {
return "upload/";
}
@NonNull
@Override
public IHttpBodyStrategy getBodyType() {
// 上传文件需要使用表单的形式提交
return RequestBodyType.FORM;
}
/** 本地图片 */
private File image;
public UpdateImageApi(File image) {
this.image = image;
}
public UpdateImageApi setImage(File image) {
this.image = image;
return this;
}
}
```
```java
EasyHttp.post(this)
.api(new UpdateImageApi(file))
.request(new OnUpdateListener