前言
各種各樣的網(wǎng)絡(luò)框架,每次都是上網(wǎng)隨便一搜,然后照著寫一寫最簡單的用法,然后下次又遇到需要網(wǎng)絡(luò)請求的時候,又忘記怎么用了。。。好無奈。所以在這里仔細(xì)記錄一下,能加深印象和理解。
本文主要講解的有以下知識點:
- get請求
- post請求
- 基于Http的文件上傳
- 文件下載
- 加載圖片
- 支持請求回調(diào),直接返回對象,對象集合
- 支持session的保持
使用
老規(guī)矩,添加依賴
compile 'com.squareup.okhttp:okhttp:2.4.0'
而因為okhttp內(nèi)部依賴okio,所以:
compile 'com.squareup.okio:okio:1.5.0'
一.Http Get
1.創(chuàng)建okHttpClient對象
2.構(gòu)造Request對象(參數(shù)至少有url,可以通過Requesr.Builder設(shè)置更多的參數(shù))
3.newCall(request),將request對象傳入,去構(gòu)造得到Call對象。也就是將你的請求封裝成了任務(wù),既然是,就有cancel和execute方法。
4.請求加入調(diào)度,enqueue,在回調(diào)者中處理請求結(jié)果。
//創(chuàng)建okHttpClient對象
OkHttpClient mOkHttpClient = new OkHttpClient();
//創(chuàng)建一個Request
final Request request = new Request.Builder()
.url("https://github.com/hongyangAndroid")
.build();
//new call
Call call = mOkHttpClient.newCall(request);
//請求加入調(diào)度
call.enqueue(new Callback()
{
@Override
public void onFailure(Request request, IOException e)
{
}
@Override
public void onResponse(final Response response) throws IOException
{
//String htmlStr = response.body().string();
}
});
我們這里是異步的方式去執(zhí)行,當(dāng)然也支持阻塞的方式,上面我們也說了Call有一個execute()方法,你也可以直接調(diào)用call.execute()通過返回一個Response。
注意:在這里onResponse,并不是運行在UI線程。返回的response可以轉(zhuǎn)化為:
字符串:response.body().string()
二進(jìn)制字節(jié)數(shù)組:response.body().bytes()
輸入流(讀)inputsream:response.body().byteStream()
二.Http Post攜帶參數(shù)
Post與Get主要是Request的構(gòu)造不同。通過FormEncodingBuilder,添加多個String鍵值對,然后去構(gòu)造RequestBody,最后完成Request的構(gòu)造。
FormEncodingBuilder builder = new FormEncodingBuilder();
builder.add("username","一期一會");
Request request = new Request.Builder()
.url(url)
.post(builder.build())
.build();
mOkHttpClient.newCall(request).enqueue(new Callback(){});
Post提交json數(shù)據(jù)
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
f (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
POST提交鍵值對
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException {
RequestBody formBody = new FormEncodingBuilder()
.add("platform", "android")
.add("name", "bug")
.add("subject", "XXXXXXXXXXXXXXX")
.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
return response.body().string();
} else {
throw new IOException("Unexpected code " + response);
}
}
基于Http的文件上傳
先介紹一個可以構(gòu)造RequestBody的Builder,叫做MultipartBuilder(可用于表單上傳)
如果想向服務(wù)端上傳一個鍵值對username:hy和一個文件,怎么寫?看以下代碼:
File file = new File(Environment.getExternalStorageDirectory(), "balabala.mp4");
RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
RequestBody requestBody = new MultipartBuilder()
.type(MultipartBuilder.FORM)
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"username\""),
RequestBody.create(null, "張鴻洋"))
.addPart(Headers.of(
"Content-Disposition",
"form-data; name=\"mFile\";
filename=\"wjd.mp4\""), fileBody)
.build();
Request request = new Request.Builder()
.url("http://192.168.1.103:8080/okHttpServer/fileUpload")
.post(requestBody)
.build();
Call call = mOkHttpClient.newCall(request);
call.enqueue(new Callback()
{
//...
});
下載文件/下載圖片
文件和圖片區(qū)別就是在得到response.body,如何轉(zhuǎn)換。文件一般是拿到inputStream做寫文件操作,而圖片是拿到byte[]然后decode成圖片
同步Get
若返回的文件較小,可response.body.string,若文件較大,超過1mb,用流的方式來處理body.
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
異步Get.
在一個工作線程中下載文件,當(dāng)響應(yīng)可讀時回調(diào)Callback接口。讀取響應(yīng)時會阻塞當(dāng)前線程。OkHttp現(xiàn)階段不提供異步api來接收響應(yīng)體。
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
@Override public void onFailure(Request request, Throwable throwable) {
throwable.printStackTrace();
}
@Override public void onResponse(Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}
封裝
以上使用,代碼都太多了有木有,而且還很難記住用法。
在這里推薦鴻洋大神寫的OKhttpUtils工具類。挺好聽的,減少了很多代碼量,代碼也簡潔明了。
在as添加依賴即可使用該工具:
compile 'com.zhy:okhttputils:2.6.2'
或者直接添加jar包
嗯。。原來只能上傳圖片。。
那還是去這里下載吧:
https://github.com/hongyangAndroid/okhttputils
里面還有詳細(xì)的使用步驟~
下面是我第一次使用okhttp,以表單的形式,同時提交鍵值對和圖片。剛開始接觸okhttp,看了很多博客,寫出來的提交代碼都不成功。后來用okhttpUtils解決了!
public static void uploadImage(String user, String path,String name, String seabillno,final Handler mHandler){
Map<String, String> params = new HashMap<String, String>();
params.clear();
//鍵值對
params.put("user",user);
params.put("seabillno",seabillno);
params.put("token","dylpda2018");
File file=new File(path);
OkHttpUtils.post()//
.addFile("file", name, file)//圖片
.url(URL_UPLOAD_PICTURE)
.params(params)//
.build()//
.execute(new StringCallback() {
@Override
public void onError(Call call, Exception e, int i) {
}
@Override
public void onResponse(String s, int i) {
System.out.println( "onSuccess: "+e);
Message message=Message.obtain();
message.what= Constants.UPLOAD_PIC_SUCCESS;
message.obj=s;
mHandler.sendMessage(message);
System.out.println(s);
}
});
}
參考文章:
https://blog.csdn.net/lmj623565791/article/details/47911083
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html