用Okhttp已有一段时日,奈何,自我感觉依旧处于多脸懵逼的状态,遂提笔画记一番。
一、添加依赖
首先。你得先知道ok的最新版本。也就是去OK的github的老窝看下
https://github.com/square/okhttp
然后,去app/build.gradle 添加相应的依赖
类似这个:
dependencies {
implementation "com.squareup.okhttp3:okhttp:3.14.0"}
二、构建okhttp的实例
嗯。正题,okhttp怎么用?先得弄个实例出来,有三种方式,三种之间的区别已在注释中倾述:
private HttpUtil() {
//第一种.通过配置ok的各种功能,来构建它的实例,就像组装电脑一样
okHttpClient = new OkHttpClient.Builder()
//连接超时
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
//读取超时
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
//写超时
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
//拦截器
.addInterceptor(new LoggingInterceptor()).build();
//第二种.通过现有实例去创建一个实例
okHttpClient=okHttpClient.newBuilder().build();
//第三种.默认构造创建实例
okHttpClient=new OkHttpClient();
//这三种的区别是:稍后更精彩,哈哈哈
}
三、配置Request请求体
那么,实例撸出来后,要干嘛?配置一堆方法+参数呗,但是,你得先告诉ok这家伙,你要访问什么地址吧?就是去哪个服务器访问。假设你要访问百度是不是?那就好,来,先丢个变量到内存里放着:
//这个是百度的域名
String url = "http://wwww.baidu.com";
但是,url给谁用?就是,谁用这个地址?okHttpClient吗?差不多,但毕竟 okHttpClient 日理万机,交给相关部门去调度就好,于是乎,Request 部门主动请缨,Request说它门下有一位置挺适合安置 url 的,然后,就出现了以下一幕:
final Request request=new Request.Builder()
//这不是刚刚的百度域名所在的变量嘛
.url(url)
.build();
你也许会好奇,Request 的职责是啥。其实也没啥,主要的也就是那么几项,例如,
1.客户端向服务端请求不是有POST和GET两种方式吗?它负责
2.如果你要传json或者文件或者啥到服务器,那么,你要事先告诉服务器,你的丢给服务器的内容类型是啥吧?那么,你就要事先把这类型(这内容类型人称 Content-Type)放到网络请求头文件 Header 里吧? 它负责
3.第二点说的 json啊 文件啊 啥的,不是直接丢在Request 里面的,是先放在Request 中的 RequestBody 里面的,也就是说,要上传数据啥的,它负责
四、配置Call
嗯,配置好 Request 的东西后,看下,嗯,可以开始执行网络请求了,瞄了一圈,发现,okHttpClient 这玩意,不能直接访问网络,要命令 Call 这家伙去干这事,Call 是啥? Call 是接口...嗯,没毛病,看来有人实现了它的相关方法 ...emmm 你猜 Call 是谁生出来的?胸手就是它:okHttpClient,okHttpClient 通过出其不意的方法 newCall ,把Call 搞出来。对了,newCall 它会要求接收一个参数 Request 这个请求内容。嗯,然后出现了以下一幕:
final Call call=okHttpClient.newCall(request);
五、提交异步请求
Call这个家伙拐到了Request 之后呢,就开车了,调戏服务器了...
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
GyLog.d("onFailure getMessage"+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
GyLog.d(" response.code() "+response.code()
+" response.message() "+response.message());
}
});
六、瞄一下请求结果
然后,结果只有两个,不成功便成仁,调戏失败onFailure?没关系,它会告诉Call, 失败的原因都在onFailure的参数 IOException 里了,回去自己反省下就好。成功的话,请接收OnResponse里的Response, Response里有不少好东西的,例如 ResponseBody 啦,Code 啦, Message 啦...此时,ResponseBody才是你最想要的,例如服务器返回的数据,一般都放在这里,code是状态码,一般200是成功撩妹的意思,其他的码结果都不咋地,message是状态信息,可能是“OK”,"查询成功",之类的好信息,也可能是"查询异常"之类的。看下面:
七、浅析两下
无论如何,以上过程算是成功地搞了一次网络请求。但是,这仅仅是okhttp的一小块知识点的运用而已。不过得说一下相关的某些东西,首先,这种方式属于http请求方式中的GET请求,然后,这种方式算是异步请求,至于啥区别,啧啧,这里先不说。那么,有异步请求就有同步请求,同步是怎样的?没啥大不同,请看代码:
new Thread(() -> {
try {
GyLog.d("start to get data ....");
Response response=call.execute();
GyLog.d(" response.code() "+response.code()
+" response.message() "+response.message());
} catch (IOException e) {
e.printStackTrace();
}
}).start();
你会发现,直接在execute方法后,等回应数据了。多么,放荡,主线程岂不是卡死在这里?啧啧,这也是同步请求的特色所在,所以,这方法才放在子线程中执行。Android3.0
以后已经不允许在主线程访问网络。那么,执行结果?看图:
八、瞎贴代码
最后,上代码,这是构建OkHttp使用方法的代码:
public class HttpUtil {
private static final long WRITE_TIMEOUT = 30;
private static final long READ_TIMEOUT = 30;
private static final long CONNECT_TIMEOUT = 30;
String url = "http://wwww.baidu.com";
private OkHttpClient okHttpClient;
private HttpUtil() {
//1.通过配置ok的各种功能,来构建它的实例,就像组装电脑一样
okHttpClient = new OkHttpClient.Builder()
//连接超时
.connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
//读取超时
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
//写超时
.writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
//拦截器:
.addInterceptor(new LoggingInterceptor()).build();
// //2.通过现有实例去创建一个实例
// okHttpClient=okHttpClient.newBuilder().build();
// //3.默认构造创建实例
// okHttpClient=new OkHttpClient();
}
public static class Builder {
public static HttpUtil build() {
return new HttpUtil();
}
}
/**
* 同步的get请求
*/
public void synchron(){
final Request request=new Request.Builder()
.url(url)
.build();
final Call call=okHttpClient.newCall(request);
new Thread(() -> {
try {
GyLog.d("start to get data ....");
Response response=call.execute();
GyLog.d(" response.code() "+response.code()
+" response.message() "+response.message());
} catch (IOException e) {
e.printStackTrace();
}
}).start();
}
/**
* 异步的get请求
*/
public void asynchronous(){
final Request request=new Request.Builder()
.url(url)
.build();
final Call call=okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
GyLog.d("onFailure getMessage"+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
GyLog.d(" response.code() "+response.code()
+" response.message() "+response.message());
}
});
}
}
这是调用okhttp的代码
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
HttpUtil.Builder.build().synchron();
}
}
到目前为止,这是okhttp最基本的GET请求用法,图谱如下: