前言
上个知识点介绍了OKHttp的基本使用,在Activity中写了大量访问网络的代码,这种代码写起来很无聊,并且对技术没什么提升。在真实的企业开发中,肯定是把这些代码封装起来,做一个库,给Activity调用。
封装之前我们需要考虑以下这些问题:
- 封装基本的公共方法给外部调用。get请求,Post请求,PostFile
- 官方建议OkHttpClient实例只new一次,那我们网络请求库可以做成单例模式。
- 如果同一时间访问同一个api多次,我们是不是应该取消之前的请求?
- 如果用户连接Http代理了,就不让访问,防止用户通过抓包工具看我们的接口数据。
- 每个接口都要带上的参数如何封装?例如app版本号,设备号,登录之后的用户token,这些参数可能每次请求都要带上。
- 返回的json字符串转成实体对象
- 访问服务器是异步请求,如何在主线程中调用回调接口?
代码实现
首先需要在线引用以下三个依赖库
compile 'com.squareup.okhttp3:okhttp:3.2.0' //okhttp
compile 'com.google.code.gson:gson:2.7' //解析jsons数据
compile 'io.github.lizhangqu:coreprogress:1.0.2' //上传下载回调监听
新建一个HttpConfig类,用来配置一些请求参数,存储请求服务器的公共参数。设置连接时间等。。。
public class HttpConfig {
private boolean debug=false;//true:debug模式
private String userAgent="";//用户代理 它是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
private boolean agent=true;//有代理的情况能不能访问,true:有代理能访问 false:有代理不能访问
private String tagName="Http";
private int connectTimeout=10;//连接超时时间 单位:秒
private int writeTimeout=10;//写入超时时间 单位:秒
private int readTimeout=30;//读取超时时间 单位:秒
//通用字段
private List<Nameva luePair> commonField=new ArrayList<>();
public boolean isDebug() {
return debug;
}
public void setDebug(boolean debug) {
this.debug = debug;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public boolean isAgent() {
return agent;
}
public void setAgent(boolean agent) {
this.agent = agent;
}
public String getTagName() {
return tagName;
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
public List<Nameva luePair> getCommonField() {
return commonField;
}
public int getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public int getWriteTimeout() {
return writeTimeout;
}
public void setWriteTimeout(int writeTimeout) {
this.writeTimeout = writeTimeout;
}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
/**
* 更新参数
* @param key
* @param value
*/
public void updateCommonField(String key,String value){
boolean result = true;
for(int i=0;i<commonField.size();i++){
Nameva luePair nameva luePair = commonField.get(i);
if(nameva luePair.getName().equals(key)){
commonField.set(i,new Nameva luePair(key,value));
result = false;
break;
}
}
if(result){
commonField.add(new Nameva luePair(key,value));
}
}
/**
* 删除公共参数
* @param key
*/
public void removeCommonField(String key){
for(int i=commonField.size()-1;i>=0;i--){
if(commonField.get(i).equals("key")){
commonField.remove(i);
}
}
}
/**
* 添加请求参数
* @param key
* @param value
*/
public void addCommonField(String key,String value){
commonField.add(new Nameva luePair(key,value));
}
}
我们给服务器提交表单数据都是通过name跟vulue的形式提交数据,封装了Nameva luePair类。如果是上传文件,isFile设置true就行。
public class Nameva luePair {
private String name;//请求名称
private String value;//请求值
private boolean isFile=false;//是否是文件
public Nameva luePair(String name, String value){
this.name=name;
this.value = value;
}
public Nameva luePair(String name, String value,boolean isFile){
thi