http
請(qǐng)求主要是Get
和Post
。二者都分為的同步和異步請(qǐng)求型宝。
Get和Post的區(qū)別:
Get用來(lái)做簡(jiǎn)單的數(shù)據(jù)請(qǐng)求稠诲,請(qǐng)求的數(shù)據(jù)寫在地址上侦鹏,比如:
http://www.reibang.com/search?q=bilibili&page=1&type=notes
其中http://www.reibang.com/
是主機(jī)地址search
后面的?q=bilibili&page=1&type=notes
是你的請(qǐng)求信息,以鍵值對(duì)的形式直接加載地址上臀叙,用&符號(hào)隔開,任何人都看得到价卤。所以GET請(qǐng)求是不安全的劝萤。一般不重要的請(qǐng)求,并且你的請(qǐng)求信息的數(shù)據(jù)量不大的就可以用GET請(qǐng)求慎璧。
POST算是GET請(qǐng)求的升級(jí)版床嫌。它將請(qǐng)求信息寫在RequestBody里面,RequestBody可以裝很多東西胸私,比如GET請(qǐng)求的鍵值對(duì)信息厌处,用戶賬號(hào)登錄就可以用POST請(qǐng)求啦。也可以上傳文件岁疼,這些是GET請(qǐng)求不能的阔涉。
OkHttp 請(qǐng)求流程:(基于okhttp3)
1 . 創(chuàng)建OkhttpClient。(注:全局最好只創(chuàng)建1個(gè)OkHttpClient捷绒,推薦使用單例模式創(chuàng)建)
OkhttpClient mClient = new OkhttpClient();
2 . mClient執(zhí)行newCall將Request轉(zhuǎn)化成一個(gè)Call瑰排。Request后面再說(shuō)。
Call call = mClient.newCall(Request request)
3 . 最后call執(zhí)行excute同步執(zhí)行暖侨,enqueue異步執(zhí)行
call.enqueue(Callback calBack)//異步執(zhí)行
或者Response res = call.excute();//線程阻塞
3.1 Callback中重寫兩個(gè)方法
new Callback() {
@Override public void onFailure(Request request, Throwable throwable) {
throwable.printStackTrace();
}
@Override public void onResponse(Response response) throws IOException {
//對(duì)response處理
}
3.2 上面的Response代表Http請(qǐng)求的響應(yīng)椭住。
- response.body()是ResponseBody類代表響應(yīng)體,可以通過(guò)responseBody.string()獲得字符串的表達(dá)形式字逗。
- responseBody.bytes()獲得字節(jié)數(shù)組的表達(dá)形式, 這兩種形式都會(huì)把文檔加入到內(nèi)存京郑。
- 也可以通過(guò)responseBody.charStream()和responseBody.byteStream()返回流來(lái)處理。
4 . Request主要通過(guò)Request.Builder來(lái)構(gòu)建
Request.Builder() builder = new Request.Builder();
GET請(qǐng)求
Request request = builder.url(url)//請(qǐng)求地址
.get()//請(qǐng)求方法葫掉,不寫默認(rèn)GET方法
.build();
POST請(qǐng)求
Request request = builder.url(url)
.Post(RequestBody requestBody)//這個(gè)就是請(qǐng)求體
.build();
4.1 RequestBody的構(gòu)建
從需求分析有:表單提交些举、文件提交,字符串挖息,前面幾種的組合提交金拒。
- 表單
RequestBody requestBody = new FormBody.Builder()
.add("q", "bilibili")//此處應(yīng)為鍵值對(duì)
.add("page","1")
.build();
- 字符串
RequestBody requestBody = RequestBody.create(mMediaType, string)
//POST提交文件需要請(qǐng)求頭里加上文件的類型
//MediaType表示了文件類型
//可以這樣寫 ,表示是text中的x-markdowm類型套腹,字符集為UTF-8
//MediaType mMediaType = MediaType.parse("text/x-markdown; charset=utf-8");
- 文件
File file = new File();
RequestBody requestBody = RequestBody.create(mMediaType, file)
- io流
RequestBody requestBody = new RequestBody() {
@Override public MediaType contentType() {
return mMediaType;
}
@Override public void writeTo(BufferedSink sink) throws IOException {
//sink上傳數(shù)據(jù)流
}
}
- 組合分塊提交
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("title", "name")
.addFormDataPart("image", "icon.jpg",RequestBody.create(mMediaType, new File(".../icon.jpg")))
.build();
//本次提交了用戶名和圖片
5. 緩存
在創(chuàng)建OKHttpClient后調(diào)用OKHttpClient .setCache(Cache cache)可以設(shè)置緩存绪抛。也可以使用OkHttpClient.Builder設(shè)置更多其他屬性。
File cache = getExternalCacheDir();
int cacheSize = 10 * 1024 * 1024;//10M
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)//超時(shí)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.cache(new Cache(cache.getAbsoluteFile(), cacheSize));
OkHttpClient mOkHttpClient=builder.build();
在使用了緩存后电禀,如果已經(jīng)緩存了請(qǐng)求結(jié)果幢码,第二次將直接讀取緩存,而不會(huì)連接網(wǎng)絡(luò)再次請(qǐng)求尖飞。當(dāng)我們需要網(wǎng)站數(shù)據(jù)更新了就獲取不了最新數(shù)據(jù)症副,所以在Request.Builder
中可以使用chacheControl(ChacheControl.FORCE_NETWORK )
讓Request
強(qiáng)制使用網(wǎng)絡(luò)獲取數(shù)據(jù)而不使用緩存店雅。將ChacheControl.FORCE_NETWORK
換成ChacheControl.FORCE_CACHE
就是強(qiáng)制使用緩存。但是贞铣,如果沒(méi)有緩存的話闹啦,就報(bào)504
錯(cuò)誤。(Request.Builder
除了new
一個(gè)以外辕坝,還可以通過(guò)已存在的request.newBuilder()
得到)
6. 取消請(qǐng)求
當(dāng)一個(gè)call
執(zhí)行了enqueue()
或者excute()
還沒(méi)執(zhí)行完畢窍奋,比如onResponse
還沒(méi)執(zhí)行,就可以使用call.cancel()
取消請(qǐng)求酱畅。否則會(huì)IOException
琳袄。