超簡單的okhttp封裝工具類(上)

 

版權聲明:轉載請註明出處:http://blog.csdn.net/piaomiao8179 https://blog.csdn.net/piaomiao8179/article/details/70811973

前言:

說起訪問網絡,很天然的會用到okHttp,雖然okhttp已經封裝的比較完善,
調用也比較方便,但對於向我這樣比較懶的人,okhttp的調用仍是略顯複雜,
每次都要寫一樣重複的代碼,簡直不能忍受,那就封裝如下一句話調用完畢,豈不快哉。。。
廢話很少說,請抓穩扶好,老司機,走起。。。
  • 1
  • 2
  • 3
  • 4

重要的事情提一提:看不懂的文章最後有完整代碼,看看完整版應該就沒問題了。java

okHttp使用流程

沒有什麼是一張圖說不清的,走起
  • 1

這裏寫圖片描述

高逼格的封裝開始

網絡訪問框架通常都須要單例模式(singleton),首先咱們也進行單利模式。
1 首先私有化構造器,讓別人不能new出其它實例。
2 聲明該類的一個靜態成員變量實例,本篇爲instance
3 聲明一個公有的方法getInstance提供給調用者本類實例。

 /**
 * 網絡訪問要求singleton
 */
private static OkHttpUtils instance;

// 必需要用的okhttpclient實例,在構造器中實例化保證單一實例
private OkHttpClient mOkHttpClient;
private OkHttpUtils() {
    /**
     * okHttp3中超時方法移植到Builder中
     */
    mOkHttpClient = (new OkHttpClient()).newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(10, TimeUnit.SECONDS)
                .writeTimeout(30, TimeUnit.SECONDS)
                .build();


}

public static OkHttpUtils getInstance() {
    if (instance == null) {
        synchronized (OkHttpUtils.class) {
            if (instance == null) {
                instance = new OkHttpUtils();
            }
        }
    }

    return instance;
}

上面代碼在構造器中實例化出了okHttpClient的實例,既然咱們這個幫助類是單例的,那麼構造器中的okHttpClient也只會走一次,一定也是單實例的。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

提供GET和POST兩種訪問方式的方法

既然是工具類,確定要更加簡單,此處咱們須要提供針對GET和POST兩種方式的訪問方法。
  • 1

1.工具類爲GET訪問方式提供的方法

/**
 * 對外提供的Get方法訪問
 * @param url
 * @param callBack
 */
public void Get(String url, MyCallBack callBack) {
    /**
     * 經過url和GET方式構建Request
     */
    Request request = bulidRequestForGet(url);
    /**
     * 請求網絡的邏輯
     */
    requestNetWork(request, callBack);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2.工具類爲POST訪問方式提供的方法(表單數據)

/**
 * 對外提供的Post方法訪問
 * @param url
 * @param parms: 提交內容爲表單數據
 * @param callBack
 */
public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) {
    /**
     * 經過url和POST方式構建Request
     */
    Request request = bulidRequestForPostByForm(url, parms);
    /**
     * 請求網絡的邏輯
     */
    requestNetWork(request, callBack);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

3.工具類爲POST訪問提供方法(JSON數據)

/**
 * 對外提供的Post方法訪問
 * @param url
 * @param json: 提交內容爲json數據
 * @param callBack
 */
public void PostWithJson(String url, String json, MyCallBack callBack) {
    /**
     * 經過url和POST方式構建Request
     */
    Request request = bulidRequestForPostByJson(url, json);
    /**
     * 請求網絡的邏輯
     */
    requestNetWork(request, callBack);

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

從這兩個方法,咱們能看到咱們須要構建GET和POST訪問方式對應的Request對象和咱們自定義的MycallBack接口,下面先來看一下構建Request對象。json

構建Request對象

爲了你們更好的理解封裝流程,首先請你們回顧一下okhttp的使用流程:
mOkHttpClient.newCall(request).enqueue(new Callback() {})
  • 1
  • 2

1.首先咱們來看構建GET須要的Request對象,這個也是最簡單的。markdown

/**
 * GET方式構建Request
 * @param url
 * @return
 */
private Request bulidRequestForGet(String url) {

    return new Request.Builder()
            .url(url)
            .get()
            .build();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

2.構建提交表單數據的Request對象網絡

/**
 * POST方式構建Request {Form}
 * @param url
 * @param parms
 * @return
 */
private Request bulidRequestForPostByForm(String url, Map<String, String> parms) {

    FormBody.Builder builder = new FormBody.Builder();

    if (parms != null) {
        for (Map.Entry<String, String> entry :
                parms.entrySet()) {
            builder.add(entry.getKey(), entry.getValue());
        }

    }
    FormBody body = builder.build();


    return new Request.Builder()
            .url(url)
            .post(body)
            .build();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3.構建提交json數據的Request對象app

/**
 * POST方式構建Request {json}
 * @param url
 * @param json
 * @return
 */
private Request bulidRequestForPostByJson(String url, String json) {
    RequestBody body = RequestBody.create(JSON, json);

    return new Request.Builder()
            .url(url)
            .post(body)
            .build();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

開始處理聯網邏輯

上述代碼及分析基本上把簡單封裝的東西講完了,有了okhttpclient和request對象咱們須要處理聯網邏輯了,也就是上述的 requestNetWork方法。

 private void requestNetWork(Request request, MyCallBack callBack) {

    /**
     * 處理連網邏輯,此處只處理異步操做enqueue
     */
    callBack.onLoadingBefore(request);

    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            callBack.onFailure(request, e);
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                callBack.onSuccess(response);
            } else {
                callBack.onError(response);
            }
        }
    });


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

MyCallBack對象分析

看到此處,估計有人會一臉懵逼,這個MyCallBack是個什麼鬼。
其實這是我定義的一個接口,那麼爲何要定義她呢。由於咱們在使用咱們的工具類的時候,訪問網絡成功後確定會有數據返回,咱們怎麼處理呢,okhttp內部經過一個callBack把數據回調回來,那麼咱們本身封裝的工具類不妨仿照他的作法  定義一個接口回調Response的內容。貼一下接口的內容

interface MyCallBack {

void onLoadingBefore(Request request);

void onSuccess(Response response);

void onFailure(Request request, Exception e);

void onError(Response response);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

}框架

封裝進階

看到此處,以爲封裝已經完結了,不不不,還有一個重要的問題,不處理的話會致使崩潰的,這個問題就是,咱們定義接口回調的地方是在子線程,而咱們的Response很明顯須要拿回到主線程進行UI的更新,因此訪問網絡的方法requestNetWork須要經過Handler把子線程的Resonse發送到主線程,請看詳細實現。
private void requestNetWork(Request request, MyCallBack callBack) {異步

/**
     * 處理連網邏輯,此處只處理異步操做enqueue
     */
    callBack.onLoadingBefore(request);

    mOkHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            mHandler.post(() -> callBack.onFailure(request, e));

        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if (response.isSuccessful()) {
                mHandler.post(() -> callBack.onSuccess(response));
            } else {
                mHandler.post(() -> callBack.onError(response));
            }
        }
    });


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

結束語

此工具類尚未完善,下篇文章繼續完善,待完善內容:返回Resonpse直接解析成javaBean返回。
  • 1

完整代碼

public class OkHttpUtils { /** * 網絡訪問要求singleton */ private static OkHttpUtils instance; // 必需要用的okhttpclient實例,在構造器中實例化保證單一實例 private OkHttpClient mOkHttpClient; public static final MediaType JSON = MediaType. parse("application/json; charset=utf-8"); private Handler mHandler; private OkHttpUtils() { /** * okHttp3中超時方法移植到Builder中 */ mOkHttpClient = (new OkHttpClient()).newBuilder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS) .build(); mHandler = new Handler(Looper.getMainLooper()); } public static OkHttpUtils getInstance() { if (instance == null) { synchronized (OkHttpUtils.class) { if (instance == null) { instance = new OkHttpUtils(); } } } return instance; } /** * 對外提供的Get方法訪問 * @param url * @param callBack */ public void Get(String url, MyCallBack callBack) { /** * 經過url和GET方式構建Request */ Request request = bulidRequestForGet(url); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param parms: 提交內容爲表單數據 * @param callBack */ public void PostWithFormData(String url, Map<String, String> parms, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByForm(url, parms); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * 對外提供的Post方法訪問 * @param url * @param json: 提交內容爲json數據 * @param callBack */ public void PostWithJson(String url, String json, MyCallBack callBack) { /** * 經過url和POST方式構建Request */ Request request = bulidRequestForPostByJson(url, json); /** * 請求網絡的邏輯 */ requestNetWork(request, callBack); } /** * POST方式構建Request {json} * @param url * @param json * @return */ private Request bulidRequestForPostByJson(String url, String json) { RequestBody body = RequestBody.create(JSON, json); return new Request.Builder() .url(url) .post(body) .build(); } /** * POST方式構建Request {Form} * @param url * @param parms * @return */ private Request bulidRequestForPostByForm(String url, Map<String, String> parms) { FormBody.Builder builder = new FormBody.Builder(); if (parms != null) { for (Map.Entry<String, String> entry : parms.entrySet()) { builder.add(entry.getKey(), entry.getValue()); } } FormBody body = builder.build(); return new Request.Builder() .url(url) .post(body) .build(); } /** * GET方式構建Request * @param url * @return */ private Request bulidRequestForGet(String url) { return new Request.Builder() .url(url) .get() .build(); } private void requestNetWork(Request request, MyCallBack callBack) { /** * 處理連網邏輯,此處只處理異步操做enqueue */ callBack.onLoadingBefore(request); mOkHttpClient.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { mHandler.post(() -> callBack.onFailure(request, e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { mHandler.post(() -> callBack.onSuccess(response)); } else { mHandler.post(() -> callBack.onError(response)); } } }); } } 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178

定義的接口的完整代碼ide

interface MyCallBack {

    void onLoadingBefore(Request request); void onSuccess(Response response); void onFailure(Request request, Exception e); void onError(Response response); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
相關文章
相關標籤/搜索