【Android】OkHttp3總結與封裝
開始使用
在app目錄下的build.gradle中新增依賴:
implementation 'com.squareup.okhttp3:okhttp:3.13.1' implementation 'com.squareup.okio:okio:2.2.2'
GET方法
OkHttpClient client = new OkHttpClient.Builder().build(); Request.Builder builder = new Request.Builder().url(url); builder.method("GET", null); Request request = builder.build(); 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 { ... } });
GET引數的傳遞可以使用拼接字串的方式直接拼接到url中。
POST方法
OkHttpClient client = new OkHttpClient.Builder().build(); FormBody.Builder formBody = new FormBody.Builder(); formBody.add(key,value); ... // 新增引數 RequestBody form = formBody.build(); Request.Builder builder = new Request.Builder(); Request request = builder.post(form) .url(url) .build(); 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 { ... } });
封裝
由於OkHttp傳送請求的方式比較繁瑣,需要構建許多引數,所以需要我們自己進行封裝,以下是我的封裝方式:
/** - @author:y4ngyy */ public class HttpClient { private OkHttpClient client; private static HttpClient mClient; private Context context; private HttpClient(Context c) { context = c; client = new OkHttpClient.Builder() .cookieJar(new PersistentCookieJar(new SetCookieCache(), new SharedPrefsCookiePersistor(context))) .followRedirects(true) .followSslRedirects(true) .build(); } public static HttpClient getInstance(Context c){ if (mClient == null) { mClient = new HttpClient(c); } returnmClient; } // GET方法 public void get(String url, HashMap<String,String> param, MyCallback callback) { // 拼接請求引數 if (!param.isEmpty()) { StringBuffer buffer = new StringBuffer(url); buffer.append('?'); for (Map.Entry<String,String> entry: param.entrySet()) { buffer.append(entry.getKey()); buffer.append('='); buffer.append(entry.getValue()); buffer.append('&'); } buffer.deleteCharAt(buffer.length()-1); url = buffer.toString(); } Request.Builder builder = new Request.Builder().url(url); builder.method("GET", null); Request request = builder.build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { callback.failed(e); } @Override public void onResponse(Call call, Response response) throws IOException { callback.success(response); } }); } public void get(String url, MyCallback callback) { get(url, new HashMap<String, String>(), callback); } // POST 方法 public void post(String url, HashMap<String, String> param, MyCallback callback) { FormBody.Builder formBody = new FormBody.Builder(); if(!param.isEmpty()) { for (Map.Entry<String,String> entry: param.entrySet()) { formBody.add(entry.getKey(),entry.getValue()); } } RequestBody form = formBody.build(); Request.Builder builder = new Request.Builder(); Request request = builder.post(form) .url(url) .build(); Call call = client.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { callback.failed(e); } @Override public void onResponse(Call call, Response response) throws IOException { callback.success(response); } }); } public interface MyCallback { void success(Response res) throws IOException; void failed(IOException e); } }
想法有以下幾點:
-
在
get()
和post()
方法中,將需要的引數以HashMap傳遞鍵值對,並把相應操作封裝。 -
第二個
get()
過載是考慮到不需要引數的GET請求的情況。 -
留下
myCallback
介面來對不同請求做處理。 - 由於需要保持cookie來做登入等操作,所以用到了第三方庫PersistentCookieJar
- 考慮到cookie的問題,在不同的activity間需要使用同一個例項才行,有想過使用Intent序列化傳遞物件,但由於activity太多,傳遞太繁瑣,所以直接寫成單例模式。
對於OkHttp的原始碼還沒有深究,有時間再繼續研究。
只是菜雞一個..有錯還請指正..繼續努力學習