OKHTTP
引用
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
權(quán)限配置
<user_permissions android:name="android.permissions.INTETNET"/>
測(cè)試URL
https://www.httpbin.org/
同步請(qǐng)求
new Thread(new Runnable() {
@Override
public void run() {
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("https://www.httpbin.org/")
.get().build();
Call call = client.newCall(request);
try {
Response response = call.execute();
Log.i(TAG, "response:"+response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
異步請(qǐng)求
OkHttpClient client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.SECONDS).build();
Request request = new Request.Builder().url("https://www.httpbin.org/")
.get().build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.i("MyTest", "Fail e:"+e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i("MyTest", response.body().string());
}
});
異步get請(qǐng)求
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivityLog";
private Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//測(cè)試get請(qǐng)求
testOkhttpGet();
}
/**
* 測(cè)試okhttp的get方法
*/
private void testOkhttpGet() {
String url = "http://api.k780.com/?app=weather.history";
okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();
OkHttpClient okHttpClient = new OkHttpClient();
final Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Message message = Message.obtain();
message.what = 0;
message.obj = e.getMessage();
mHandler.sendMessage(message);
Log.d(TAG, "onFailure: " + message.obj.toString());
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
Message message = Message.obtain();
message.what = 1;
message.obj = response.body().string();//string不能調(diào)用兩次 被調(diào)用一次就關(guān)閉了矢腻,這里調(diào)用兩次會(huì)報(bào)異常
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
});
}
}
異步測(cè)試post請(qǐng)求
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivityLog";
private Handler mHandler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//測(cè)試get請(qǐng)求
testOkhttpPost();
}
/**
* 測(cè)試okhttp的post方法
*/
private void testOkhttpPost() {
String url = "http://api.k780.com/?app=weather.history";//
// &weaid=1&date=2018-08-13&appkey=10003&sign=b59bc3ef6191eb9f747dd4e83c99f2a4&format=json";
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("weaid", "1")
.add("date", "2018-08-13")
.add("appkey", "10003")
.add("sign", "b59bc3ef6191eb9f747dd4e83c99f2a4")
.add("format", "json")
.build();
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.post(body)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Message message = Message.obtain();
message.what = 0;
message.obj = e.getMessage();
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
@Override
public void onResponse(Call call, okhttp3.Response response) throws IOException {
Message message = Message.obtain();
message.what = 1;
message.obj = response.body().string();//string不能調(diào)用兩次 被調(diào)用一次就關(guān)閉了赘来,這里調(diào)用兩次會(huì)報(bào)異常
mHandler.sendMessage(message);
Log.d(TAG, "response: " + message.obj.toString());
}
});
}
}
Retrofit
一:Retrofit是什么唐断?
準(zhǔn)確來說费尽,Retrofit 是一個(gè) RESTful 的 HTTP 網(wǎng)絡(luò)請(qǐng)求框架的封裝至会。
原因:網(wǎng)絡(luò)請(qǐng)求的工作本質(zhì)上是 OkHttp 完成用含,而 Retrofit 僅負(fù)責(zé) 網(wǎng)絡(luò)請(qǐng)求接口的封裝
我們先來看看下面這個(gè)圖:
上圖說明了如下幾點(diǎn):
- App應(yīng)用程序通過 Retrofit 請(qǐng)求網(wǎng)絡(luò)矮慕,實(shí)際上是使用 Retrofit 接口層封裝請(qǐng)求參數(shù)、Header啄骇、Url 等信息痴鳄,之
后由 OkHttp 完成后續(xù)的請(qǐng)求操作。 - 在服務(wù)端返回?cái)?shù)據(jù)之后缸夹,OkHttp 將原始的結(jié)果交給 Retrofit痪寻,Retrofit根據(jù)用戶的需求對(duì)結(jié)果進(jìn)行解析。
所以虽惭,網(wǎng)絡(luò)請(qǐng)求的本質(zhì)仍舊是OkHttp完成的橡类,retrofit只是幫使用者來進(jìn)行工作簡(jiǎn)化的,比如配置網(wǎng)絡(luò)趟妥,處理數(shù)據(jù)等
工作猫态,提高這一系列操作的復(fù)用性。這也就是網(wǎng)上流行的一個(gè)不太準(zhǔn)確的總結(jié):okhttp是瑞士軍刀披摄,retrofit則是講這
邊瑞士軍刀包裝從了一個(gè)非常好用的指甲鉗。
二: Retrofit 對(duì)Okhttp做了什么
Retrofit并沒有改變網(wǎng)絡(luò)請(qǐng)求的本質(zhì)勇凭,也無需改變疚膊,因?yàn)镺khttp已經(jīng)足夠強(qiáng)大,Retrofit的封裝可以說是很強(qiáng)大虾标,里
面涉及到一堆的設(shè)計(jì)模式,可以通過注解直接配置請(qǐng)求寓盗,可以使用不同的http客戶端,雖然默認(rèn)是用http 璧函,可以使用
不同Json Converter 來序列化數(shù)據(jù)傀蚌,同時(shí)提供對(duì)RxJava的支持,使用Retrofit + OkHttp + RxJava 可以說是目前比較
潮的一套框架蘸吓,但是需要有比較高的門檻善炫。
下面我們來對(duì)比一下OKhttp網(wǎng)絡(luò)請(qǐng)求和 retrofit網(wǎng)絡(luò)請(qǐng)求的區(qū)別。
2.1. Okhttp請(qǐng)求總結(jié)
[大家先看下面okhttp請(qǐng)求的樣例代碼]
private void testOkHttp() throws IOException {
//Step1
final OkHttpClient client = new OkHttpClient();
//Step2
final Request request = new Request.Builder()
.url("https://www.google.com.hk").build();
//Step3
Call call = client.newCall(request);
//step4 發(fā)送網(wǎng)絡(luò)請(qǐng)求库继,獲取數(shù)據(jù)箩艺,進(jìn)行后續(xù)處理
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(TAG,response.toString());
Log.i(TAG,response.body().string());
}
});
}
「解析一下上面的代碼」
Step1:創(chuàng)建HttpClient對(duì)象窜醉,也就是構(gòu)建一個(gè)網(wǎng)絡(luò)類型的實(shí)例,一般會(huì)將所有的網(wǎng)絡(luò)請(qǐng)求使用同一個(gè)單例對(duì)象艺谆。
Step2:構(gòu)建Request榨惰,也就是構(gòu)建一個(gè)具體的網(wǎng)絡(luò)請(qǐng)求對(duì)象,具體的請(qǐng)求url静汤,請(qǐng)求頭琅催,請(qǐng)求體等等。
Step3:構(gòu)建請(qǐng)求Call虫给,也就是將具體的網(wǎng)絡(luò)請(qǐng)求與執(zhí)行請(qǐng)求的實(shí)體進(jìn)行綁定恢暖,形成一個(gè)具體的正式的可執(zhí)行實(shí)體。
Step4: 后面就進(jìn)行網(wǎng)絡(luò)請(qǐng)求了狰右,然后處理網(wǎng)絡(luò)請(qǐng)求的數(shù)據(jù)了杰捂。
「總結(jié)一下」
OKhttp的意義:OkHttp 是基于Http協(xié)議封裝的一套請(qǐng)求客戶端,雖然它也可以開線程棋蚌,但根本上它更偏向真正的
請(qǐng)求嫁佳,跟HttpClient, HttpUrlConnection的職責(zé)是一樣的。
Okhttp的職責(zé):OkHttp主要負(fù)責(zé)socket部分的優(yōu)化谷暮,比如多路復(fù)用蒿往,buffer緩存,數(shù)據(jù)壓縮等等湿弦。
Okhttp給用戶留下的問題:
1)用戶網(wǎng)絡(luò)請(qǐng)求的接口配置繁瑣瓤漏,尤其是需要配置請(qǐng)求body,請(qǐng)求頭颊埃,參數(shù)的時(shí)候蔬充;
2)數(shù)據(jù)解析過程需要用戶手動(dòng)拿到responsbody進(jìn)行解析,不能復(fù)用班利;
3)無法適配自動(dòng)進(jìn)行線程的切換饥漫。
那么這幾個(gè)問題誰來解決? 對(duì)罗标,retrofit庸队!