參考和轉載地址:
參考文章地址:OkHttp基礎概念解釋
轉載文章地址:Okhttp3基本使用
官方地址 https://github.com/square/okhttp
簡介OKHTTP
1. 優勢
-
支持HTTP2/SPDY,如果SPDY不可用,則通過連接池來減少請求延時
-
socket自動選擇最好路線,並支持自動重連,擁有自動維護的socket連接池,減少握手次數,減少了請求延遲,共享Socket,減少對服務器的請求次數
-
基於Headers的緩存策略減少重複的網絡請求
-
擁有Interceptors輕鬆處理請求與響應(自動處理GZip壓縮),減少了下載大小
-
當網絡出現問題時,OkHttp 會自動重試一個主機的多個 IP 地址
-
使用簡單,支持同步阻塞調用和帶回調的異步調用
2. 使用
2.1 添加依賴和權限
最新版本,可以進入官網查看。
implementation 'com.squareup.okhttp3:okhttp:3.13.1'
<uses-permission android:name="android.permission.INTERNET" />
2.2 Get同步請求:
Response response = call.execute();
2.3 Get異步請求
String url = "http://wwww.baidu.com";
OkHttpClient okHttpClient = new OkHttpClient();
final Request request = new Request.Builder()
.url(url)
.get()//默認就是GET請求,可以不寫
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, IOException e) {
LogUtils.e(TAG, "onFailure: ");
}
@Override
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
String content = response.body().string();
LogUtils.i(TAG, "onResponse: " + content);
}
});
注:response.body().string(); 只能調用一次,再次調用不會再有返回結果,所以需要緩存一下。
2.4 Post請求,請求參數爲String
post 請求需要構建RequestBody,並且RequestBody需要指定MediaType。
String 對應的
MediaType.parse("application/json; charset=utf-8")
String encodedPwd = "";
final Base64.Encoder encoder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
encoder = Base64.getEncoder();
final String text = MD5Utils.md5("123qwe");
byte[] textByte = new byte[0];
try {
textByte = text.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
encodedPwd = encoder.encodeToString(textByte);
System.out.println("編碼 encodedText ==" + encodedPwd);
}
Map<String, String> body = new HashMap<>();
body.put("phone", "15612345678");
body.put("password", encodedPwd);
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), new Gson().toJson(body));
Request request1 = new Request.Builder()
.addHeader("time", String.valueOf(System.currentTimeMillis()))
.addHeader("requestId", UUID.randomUUID().toString().replace("-", ""))
.addHeader("Content-Type", "application/json")
.addHeader("charset", "UTF-8")
.addHeader("Accept", "application/json")
.url(baseUrl + DOMAIN1 + LOGIN)
.post(requestBody)
.build();
OkHttpClient okHttpClient1 = new OkHttpClient();
okHttpClient1.newCall(request1).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d(TAG, "onFailure: " + e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d(TAG, response.protocol() + " " + response.code() + " " + response.message());
Headers headers = response.headers();
for (int i = 0; i < headers.size(); i++) {
Log.d(TAG, headers.name(i) + ":" + headers.value(i));
}
Log.d(TAG, "onResponse: " + response.body().string());
}
});
Retrofit請求API:
@POST(DOMAIN1 +LOGIN)
Observable<ResponseNull> login(@Body Map<String, String> body);
上面代碼中的body可以直接用在這裏,因爲類型一致所以並不需要轉換類型,也可以自定義。
注意:Bad request 可能是因爲類型轉換錯誤導致。
2.5 Post請求,參數爲流
RequestBody requestBody = new RequestBody() {
@Nullable
@Override
public MediaType contentType() {
return MediaType.parse("text/x-markdown; charset=utf-8");
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
sink.writeUtf8("I am Jdqm.");
}
};
2.6 Post請求,參數爲文件
File file2 = new File(picturePath);
RequestBody photo = RequestBody.create(MediaType.parse("multipart/form-data"), file2);
Retrofit請求API:
2.6 Post請求,參數爲表單
RequestBody requestBody = new FormBody.Builder()
.add("search", "Jurassic Park")
.build();
2.6 Post請求,多參數請求
MultipartBody body = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
.build();
2.6.1 普通鍵值對
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"title\""),
RequestBody.create(null, "Square Logo"))
2.6.2 文件的傳輸
.addPart(
Headers.of("Content-Disposition", "form-data; name=\"image\""),
RequestBody.create(MEDIA_TYPE_PNG, new File("website/static/logo-square.png")))
以上是文件的傳輸。
2.6.1.1 MEDIA_TYPE_PNG
- MediaType.parse(“image/png”)
- MediaType.parse(“image/*”)
- MediaType.parse(“image/jpg”)
2.6.1.2 文件名稱
Headers.of("Content-Disposition", "form-data; name=\"file\";filename=\"file.jpg\""),
RequestBody.create(MediaType.parse("image/png"), file3))
2.6.1.3 addFormDataPart
這個方法是OKHTTP對於addPart的封裝
.addFormDataPart("file", file3.getName(), RequestBody.create(MediaType.parse("image/*"), file3))
2.6.3 retrofit 多參數
@Multipart
@POST(DOMAIN2 + "/c/file/update")
Observable<Response> updatePic(@PartMap Map<String, RequestBody> params);
@Multipart:
Multipart = MultipartBody.FORM = MediaType.parse("multipart/form-data")
multipart/form-data:
指定傳輸數據爲二進制數據,例如圖片、mp3、文件;
它會將表單的數據處理爲一條消息,以標籤爲單元,用分隔符分開。既可以上傳鍵值對,也可以上傳文件。當上傳的字段是文件時,會有Content-Type來表名文件類型;content-disposition,用來說明字段的一些信息;