okHttp3 是一个 Android的基于Http的网络开源框架,是由 square 公司开发。
现在网上比较推荐的两个 Android 网络开源框架,一个是 okHttp,另一个是 Retrofit
,而 Retrofit 是根据 okHttp封装的框架。所以关于Android网络部分,okHttp是必须要学习的一个知识。
[官网地址] (https://github.com/square/okhttp)
项目中引用 okHttp3 只需要在 app 的 build.gradle 中引用 compile ‘com.squareup.okhttp3:okhttp:3.6.0’ 即可。
[慕课网洪洋大神的okHttp视频]
(http://www.imooc.com/learn/764)
[参考的简书文章]
(http://www.jianshu.com/p/964bb1b2d345)
[参考的CSDN文章]
(http://blog.csdn.net/itachi85/article/details/51190687)
1.okHttp3的基本用法
首先,不管是 Get 请求还是 Post 请求,同步或者异步,okHttp3的请求总体分为三步:
示例如下:
//构造出一个Request对象,address是访问的服务器地址,当前示例是get方式访问
Request request = new Request.Builder().url(address).get().build();
//通过上面的request对象,构造出一个Call对象,sOkHttpClient为全局的OkHttpClient对象
Call call = sOkHttpClient.newCall(request);
//call执行enqueue(异步)或者execute(同步),callback为异步执行时的回调对象
call.enqueue(callback);
2.okHttp3下的Get请求方式
/**
* Get请求方法
* @param view
*/
public void doGet(View view){
String address = baseUrl + "login?username=hblolj&password=123456";
HttpUtils.sendOkHttpRequestByGet(address, new Callback() {
//请求失败的回调
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
//请求成功的回调
@Override
public void onResponse(Call call, Response response) throws IOException {
//拿到服务器返回的数据
final String result = response.body().string();
Log.i(TAG, "onResponse: " + result);
//因为是enqueue异步执行,所以只有在主线程中才可以更新UI
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
}
});
}
/**
* HttpUtils中的Get请求方法
* @param address get方式的请求地址
* @param callback 回调对象
*/
public static void sendOkHttpRequestByGet(String address , Callback callback){
Request request = new Request.Builder().url(address).get().build();
Call call = sOkHttpClient.newCall(request);
call.enqueue(callback);
}
3.okHttp3下的Post请求方式(键值对型)
Tips:post请求默认的类型是:application/x-www-form-urlencoded
//在OkHttp3的源码中FormBody 的源码
private static final MediaType CONTENT_TYPE =
MediaType.parse("application/x-www-form-urlencoded");
根据 MediaType 的类型,post选择对上传的数据是否进行编码处理。如果为 multipart/form-data 类型表示上传的是文件,则不用进行编码处理。
/**
* Post请求方法
* @param view
*/
public void doPost(View view){
//登录接口
String address = baseUrl + "login";
Map map = new HashMap<>();
map.put("username", "hblolj");
map.put("password", "123456");
HttpUtils.sendOkHttpRequestByPost(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.i(TAG, "onResponse: " + result);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
}
}, map);
}
/**
* HttpUtils中的post请求方法
* @param address post请求的地址
* @param callback 回调对象
* @param maps post请求的参数
*/
public static void sendOkHttpRequestByPost(String address, Callback callback, Map maps){
//根据参数中的maps拼装出RequestBody,用来保存参数,默认的MediaType
RequestBody requestBody = new FormBody.Builder()
.add("username", maps.get("username"))
.add("password", maps.get("password"))
.build();
//将请求地址与请求参数设置给Request
Request request = new Request.Builder().url(address).post(requestBody).build();
//构造Call对象
Call call = sOkHttpClient.newCall(request);
//异步执行网络访问
call.enqueue(callback);
}
4.okHttp3下的Post请求方式(String型)
/**
* Post请求上传字符串
* @param view
*/
public void doPostString(View view){
String address = baseUrl + "postString";
HttpUtils.sendOkHttpRequestByPostString(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.i(TAG, "onResponse: " + result);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
}
}, "我是通过PostString传递的字符内容");
}
/**
* Post上传字符串方法
* @param address 服务器地址
* @param callback 回调对象
* @param value 上传的字符串
*/
public static void sendOkHttpRequestByPostString(String address, Callback callback, String value){
//相对于键值对类型,这里指定了MediaType
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), value);
//构造Request
Request request = new Request.Builder().url(address).post(requestBody).build();
//构造Call
Call call = sOkHttpClient.newCall(request);
//异步执行
call.enqueue(callback);
}
5.okHttp3下的Post请求方式(File型)
/**
* Post请求上传文件
* @param view
*/
public void doPostFile(View view){
String address = baseUrl + "postFile";
//从内存卡获取文件
File file = new File(Environment.getExternalStorageDirectory(), "shareimg.png");
if (!file.exists()){
Log.i(TAG, "文件不存在");
tv_result.setText("文件不存在!");
return;
}
HttpUtils.sendOkHttpRequestByPostFile(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.i(TAG, "onResponse: " + result);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
}
}, file);
}
/**
* Post方法上传文件
* @param address 完整的请求地址
* @param callback 回调对象
* @param file 上传的文件对象
*/
public static void sendOkHttpRequestByPostFile(String address, Callback callback, File file){
//指定了MediaType为application/octet-stream,并且传入File生成requestBody
RequestBody requestBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
//构造Request
Request request = new Request.Builder().url(address).post(requestBody).build();
//构造Call
Call call = sOkHttpClient.newCall(request);
//异步执行
call.enqueue(callback);
}
6.okHttp3下的文件上传
/**
* okHttp3下的文件上传
* @param view
*/
public void doUpload(View view){
String address = baseUrl + "uploadFile";
File file = new File(Environment.getExternalStorageDirectory(), "tagPicture.jpg");
if (!file.exists()){
Log.i(TAG, "文件不存在");
tv_result.setText("文件不存在!");
return;
}
HttpUtils.sendOkHttpRequestByUpload(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String result = response.body().string();
Log.i(TAG, "onResponse: " + result);
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText(result);
}
});
}
}, file);
}
/**
* okHttp3下的文件时上传
* @param address 访问的地址
* @param callback 回调对象
* @param file 上传的文件
*/
public static void sendOkHttpRequestByUpload(String address, Callback callback, File file){
//构造MultipartBody(复合Body)
MultipartBody multipartBody = new MultipartBody.Builder()
//配置上传的类型
.setType(MultipartBody.FORM)
//上传的普通键值对
.addFormDataPart("username", "hblolj")
.addFormDataPart("password", "123456")
//参数对应为name, fileName, reuqestBody
.addFormDataPart("picture", "一张照片.jpg",
//构造文件类型RequestBody
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
//构造Request
Request request = new Request.Builder().url(address).post(multipartBody).build();
//构造Call
Call call = sOkHttpClient.newCall(request);
//异步执行
call.enqueue(callback);
}
7.okHttp3下的文件下载
/**
* okhttp3下的文件下载
* @param view
*/
public void doDownloadFile(View view){
//下载地址
String address = baseUrl + "files/picture.jpg";
HttpUtils.sendOkHttpRequestByDownloadFile(address, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i(TAG, "onFailure: " + e.getMessage());
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//拿到服务器下载文件的输入流
InputStream is = response.body().byteStream();
//本地新建文件
File file = new File(Environment.getExternalStorageDirectory(), "一张照片6666.jpg");
//拿到新建文件的输出流
FileOutputStream fout = new FileOutputStream(file);
//模板代码,将下载文件的输入流写到新建文件
int len = 0;
byte[] buf = new byte[128];
while((len = is.read(buf)) != -1){
fout.write(buf, 0, len);
}
fout.flush();
fout.close();
is.close();
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_result.setText("下载成功");
}
});
}
});
}
/**
* okhttp3下的文件下载
* 找到下载地址,就是普通的Get访问
* @param address 下载地址
* @param callback 回调对象
*/
public static void sendOkHttpRequestByDownloadFile(String address, Callback callback){
Request request = new Request.Builder().url(address).get().build();
Call call = sOkHttpClient.newCall(request);
call.enqueue(callback);
}
8.okHttp3下的Session保持与缓存
/**
* 全局的okHttpClient
*/
private static OkHttpClient sOkHttpClient = new OkHttpClient.Builder().cookieJar(new CookieJar() {
private Map> cookieStore = new HashMap>();
@Override
public void saveFromResponse(HttpUrl url, List cookies) {
//根据请求的host保存cookies到内存,达到session的保存
Log.d("HttpUtils", "host: " + url.host());
cookieStore.put(url.host(), cookies);
}
@Override
public List loadForRequest(HttpUrl url) {
List cookies = cookieStore.get(url.host());
return cookies!=null?cookies : new ArrayList();
}
})
//设置连接超时时间
.connectTimeout(1500, TimeUnit.MILLISECONDS)
.readTimeout(2000, TimeUnit.MILLISECONDS)
.writeTimeout(2000, TimeUnit.MILLISECONDS)
//设置保存缓存的文件以及大小限制
.cache(new Cache(file , 10*1024*1024))
.build();
9.okHttp3的框架封装
参考开始的推荐文章