25、Android--OkHttp
阿新 • • 發佈:2021-06-29
OkHttp
OkHttp是一個優秀的網路請求框架,在使用需要新增相應的依賴:
implementation "com.squareup.okhttp3:okhttp:3.11.0"
還有請求網路的許可權:
GET請求
使用OkHttp進行Get
請求只需要四步即可完成。
// 構建OkHttpClient物件 OkHttpClient client = new OkHttpClient(); // 構造Request物件 Request request = new Request.Builder() .url("www.baidu.com") .get() .build(); //將Request封裝為Call Call call = client.newCall(request);
最後,根據需要呼叫同步或者非同步請求方法即可
同步呼叫
//同步呼叫,返回Response,會丟擲IO異常
Response response = call.execute();
非同步呼叫
//非同步呼叫,並設定回撥函式 call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { Toast.makeText(OkHttpActivity.this, "get failed", Toast.LENGTH_SHORT).show(); } @Override public void onResponse(Call call, final Response response) throws IOException { final String res = response.body().string(); runOnUiThread(new Runnable() { @Override public void run() { contentTv.setText(res); } }); } });
在使用OkHttp需要注意:
同步呼叫會阻塞主執行緒,一般不適用
非同步呼叫的回撥函式是在子執行緒,需要藉助於 runOnUiThread() 方法或者Handler來處理。
POST提交鍵值對
使用OkHttp進行Post
請求和進行Get
請求很類似,只需要五步即可完成。
// 構建OkHttpClient物件 OkHttpClient client = new OkHttpClient(); // 構建FormBody傳入引數 FormBody formBody = new FormBody.Builder() .add("username", "admin") .add("password", "admin") .build(); // 構造Request物件,將FormBody作為Post方法的引數傳入 Request request = new Request.Builder() .url("https:www.baidu.com") .post(formBody) .build(); //將Request封裝為Call Call call = client.newCall(request);
最後,呼叫請求,重寫回調方法:
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Toast.makeText(OkHttpActivity.this, "Post Failed", Toast.LENGTH_SHORT).show();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String res = response.body().string();
runOnUiThread(new Runnable() {
@Override
public void run() {
contentTv.setText(res);
}
});
}
});
POST提交字串
POST提交字串就需要使用RequestBody,其中FormBody是RequestBody的子類。
// 構建OkHttpClient物件
OkHttpClient client = new OkHttpClient();
// 構建FormBody傳入引數
RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain;charset=utf-8"), "1111111111111111");
// 構造Request物件,將FormBody作為Post方法的引數傳入
Request request = new Request.Builder()
.url("www.baidu.com")
.post(requestBody)
.build();
//將Request封裝為Call
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
上面的MediaType我們指定傳輸的是純文字,而且編碼方式是utf-8,通過上面的方式我們就可以向服務端傳送json字串。
POST上傳檔案
這裡我們以上傳一張圖片為例,演示OkHttp上傳單檔案:
OkHttpClient okHttpClient = new OkHttpClient();
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),file);
Request request = new Request.Builder()
.url("www.baidu.com")
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
如果是多檔案上傳,可以使用表單的方式來提交:
List<String> fileNames = new ArrayList<>();
fileNames.add(Environment.getExternalStorageState() + "/1.png");
fileNames.add(Environment.getExternalStorageState() + "/2.png");
OkHttpClient okHttpClient = new OkHttpClient();
MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
for (String fileName : fileNames) {
File file = new File(fileName);
builder.addFormDataPart("files", file.getName(), RequestBody.create(
MediaType.parse("multipart/form-data"), file));
}
MultipartBody multipartBody = builder.build();
Request request = new Request.Builder()
.url("www.baidu.com")
.post(multipartBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
POST提交表單
其中,MultipartBody是RequestBody的子類,提交表單需要使用它來構建RequestBody。
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
OkHttpClient okHttpClient = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("username", "admin")
.addFormDataPart("password", "admin")
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
Request request = new Request.Builder()
.url("www.baidu.com")
.post(requestBody)
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
}
});
GET下載檔案
下面將演示OkHttp使用GET請求下載檔案的例項:
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url("www.baidu.com/1.png")
.get()
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
InputStream inputStream = response.body().byteStream();
int len;
File file = new File(Environment.getExternalStorageDirectory(), "1.png");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[128];
while ((len = inputStream.read(buf)) != -1){
fos.write(buf, 0, len);
}
fos.flush();
fos.close();
inputStream.close();
}
});
可以通過流的讀取來實現檔案的上傳和下載進度顯示。
OkHttp攔截器
OkHttp的攔截器有五種內建的,除此之外還可以自定義攔截器。
- retryAndFollowUpInterceptor:重試和重定向攔截器,主要負責網路失敗重連。
- BridgeInterceptor:主要負責新增交易請求頭。
- CacheInterceptor:快取攔截器,主要負責攔截快取。
- ConnectInterceptor:網路連線攔截器,主要負責正式開啟http請求。
- CallServerInterceptor:負責傳送網路請求和讀取網路響應
這裡主要介紹使用自定義日誌攔截器來列印Logger資訊。
1)建立HttpLogger類實現HttpLoggingInterceptor.Logger
public class HttpLogger implements HttpLoggingInterceptor.Logger {
@Override
public void log(String message) {
Log.e("HttpLogInfo", message);
}
}
2) 使用OkHttpClient.Builder新增攔截器
// Add Logger Interceptor
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLogger());
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
clientBuilder.addNetworkInterceptor(loggingInterceptor);
這樣,就可以在請求網路的時候看到OkHttp的日誌資訊。
關於OkHttp還有很多內容,這裡只是簡單的介紹使用。