刚参加工作的时候,使用Apache的HttpClient 进行Android网络编程,HttpClient 是Apache的一个网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快。实现比较稳定,bug比较少,但是由于其api众多,很难在不破坏兼容性的情况下对其进行扩展。所以,Android团队对提升和优化httpclient积极性并不高。android 6.0中被删除。也会使用HttpURLConnection,HttpURLConnection是一个多用途、轻量级的http客户端。它对网络请求的封装没有HttpClient彻底,api比较简单,用起来没有那么方便。
后来开始接触Volley和OkHttp,他们有优缺点:
1、Volley是google在2013 io大会上推出的网络通信框架,特别适合处理数据量小,通信频繁的网络操作。优点是内部封装了异步线程,可直接在主线程请求网络,并处理返回的结果。同时可以取消请求,容易扩展。缺点是:面对大数据量的请求,比如下载表现糟糕,不支持https。
2、okhttp是专注于提升网络连接效率的http客户端
优点:
1)、它能实现同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力。
2)、okhttp 对http和https都有良好的支持。
3)、okhttp 不用担心android版本变换的困扰。
4)、成熟的网络请求解决方案,比HttpURLConnection更好用。 缺点:okhttp请求网络回来response是在子线程里面,不是在主线程,不能直接刷新UI,需要手动发送回主线程。没有进行封装(Retrofit解决了这个问题) 在看到OkHttp的各种优点后,尤其是对性能对提高,这让人无法拒绝。下面就来说一下okhttp的用法。
(一)引入Jar包
compile 'com.squareup.okhttp3:okhttp:3.2.0'
(二)使用方法
对于同步请求,使用realcall的execute(),分为get、post两种方式请求,在请求时需要开启子线程,请求成功后需要跳转到UI线程修改UI。
get方式如下:
public void getDatasync(){
new Thread(new Runnable() {
@Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象
Request request = new Request.Builder()
.url("http://www.baidu.com")//请求接口。如果需要传参拼接到接口后面。
.build();//创建Request 对象
Response response = null;
response = client.newCall(request).execute();//得到Response 对象
if (response.isSuccessful()) {
Log.d("kwwl","response.code()=="+response.code());
Log.d("kwwl","response.message()=="+response.message());
Log.d("kwwl","res=="+response.body().string());
//此时的代码执行在子线程,修改UI的操作请使用handler跳转到UI线程。
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
post方式如下:
private void postDataWithParame() {
OkHttpClient client = new OkHttpClient();//创建OkHttpClient对象。
FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
formBody.add("username","zhangsan");//传递键值对参数
Request request = new Request.Builder()//创建Request 对象。
.url("http://www.baidu.com")
.post(formBody.build())//传递请求体
.build();
Response response = null;
response = client.newCall(request).execute();//得到Response 对象
if (response.isSuccessful()) {
....省略
}
两者的区别在于Request的创建,post请求调用来post()方法,默认不调用使用get方式请求。
异步请求的get、post请求与同步一样,唯一不同的是同步调用RealCall的execute(),异步是RealCall的enqueue(),并调用回调函数,在两个回调函数里写具体的操作,该回调函数还是在子线程,对UI对操作要传回主线程。代码如下:
private void getDataAsync() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://www.baidu.com")
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){//回调的方法执行在子线程。
Log.d("kwwl","获取数据成功了");
Log.d("kwwl","response.code()=="+response.code());
Log.d("kwwl","response.body().string()=="+response.body().string());
}
}
});
}
注意事项:
1、回调接口的onFailure方法和onResponse执行在子线程。
2、response.body().string()方法也必须放在子线程中。当执行这行代码得到结果后,再跳转到UI线程修改UI。