1. 程式人生 > >Retrofit工具類(Retrofit二次封裝)

Retrofit工具類(Retrofit二次封裝)

本文是原創,轉載請註明,謝謝。

之前一直用的XUtils,方便快捷,但是由於與後臺對接的方式有了新的規範和模式變更,XUtils滿足不了我們新的需求,所以開始使用Retrofit,由於Retrofit本身屬於重量級的網路框架,不封裝的話在專案中會非常的繁瑣,所以有了下面這個工具類。
依賴scalars用於獲取字串,依賴Gson可以獲取到Model物件,
因為我們的解析有另外的工具類,而且後臺剛剛換框架,為了避免多次更改,所以依賴的是scalars,先獲取字串,這樣方便除錯。

    compile 'com.squareup.retrofit2:retrofit:2.2.0'
    compile 'com.squareup.retrofit2:converter-scalars:2.2.0'

先來看看Retrofit封裝之後的用法

網路請求時新增的引數我放在Map裡面,不確定是否需要傳檔案,所以Map的value用了Object佔位,每次new的時候很不自在,直接繼承了一個

public class RequestParam extends HashMap<String,Object>{

}
        RequestParam param=new RequestParam();
        param.put("name", "韋兆都");//普通字串引數
        param.put("image", new File(""));//上傳檔案
//第一個引數:URL //第二個引數:網路請求需要傳的引數,是個Map //第三個引數:回撥 HttpUtils.postRequest("www.1024.com", param, new RetrofitCallBack() { @Override public void onSuccess(Response<String> response, Call<String> call) { } @Override public
void onFailure(Call<String> call, Throwable t) { } @Override public void onException(Exception e) { } });

需要可操控的去取消網路請求時,把物件提取出來,在需要取消的時候呼叫cancel即可。

        RequestParam param=new RequestParam();
        param.put("name", "韋兆都");//普通鍵值對
        param.put("image", new File(""));//上傳檔案
        Call<String> call = HttpUtils.postRequest("www.1024.com", param, new RetrofitCallBack() {
            @Override
            public void onSuccess(Response<String> response, Call<String> call) {

            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {

            }

            @Override
            public void onException(Exception e) {

            }
        });
        //比如DaiLog關閉監聽的方法中放入
        call.cancel();

************************上面是用法 下面貼程式碼*************

首先是RetrofitInterface

public interface RetrofitInterface {


    /**
     * POST請求
     */
    @POST
    Call<String> postRequest(@Url String url, @Body RequestBody body);

    /**
     * GET請求
     */
    @GET
    Call<String> getRequest(@Url String url);



    /**
     * PUT請求
     */
    @PUT
    Call<String> putRequest(@Url String url, @Body RequestBody body);


}

看了很多Retrofit的介紹,我還是比較喜歡RequestBody這引數,合我胃口,不論是傳檔案還是傳普通的鍵值對,都可以放入這個請求體當中。至於我用@URL這個註解,也是因為比較萬能,全額替換url。

接下來是自定義回撥的介面,因為在網路請求的步驟是在工具類當中執行的非同步,所以需要來一發介面回撥。

public interface RetrofitCallBack  {

    void onSuccess(Response<String> response, Call<String> call);


    void onFailure(Call<String> call, Throwable t);


    void onException(Exception e);
}

工具類使用時呼叫下面四個方法,對應四種請求型別:


    /**
     * get請求
     * @param url
     * @param callback
     * @return
     */
    public static Call<String> getRequest(String url, RetrofitCallBack callback) {
        Call<String> connect = null;
        try {
            connect = connect(url, callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connect;
    }


    /**
     * post請求
     * @param url
     * @param map
     * @param callback
     * @return
     */
    public static Call<String> postRequest(String url, Map<String, Object> map, RetrofitCallBack callback) {
        Call<String> connect = null;
        try {
            connect = connect(POST_REQUEST, url, map, callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connect;

    }


    /**
     * delete請求
     * @param url
     * @param map
     * @param callback
     * @return
     */
    public static Call<String> deleteRequest(String url, Map<String, Object> map, RetrofitCallBack callback) {
        Call<String> connect = null;
        try {
            connect = connect(DELETE_REQUEST, url, map, callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connect;

    }


    /**
     * put請求
     * @param url
     * @param map
     * @param callback
     * @return
     */
    public static Call<String> putRequest(String url, Map<String, Object> map, RetrofitCallBack callback) {
        Call<String> connect = null;
        try {
            connect = connect(PUT_REQUEST, url, map, callback);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connect;
    }

下面方法對應網路請求中是否給請求體新增引數

get無參請求

    /**
     * 無參連線
     * @param url
     * @param callback
     */
    private static Call<String> connect(final String url, final RetrofitCallBack callback) {
        Call<String> call = getInstance().getRequest(url);
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {
                callback.onSuccess(response, call);
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                callback.onFailure(call, t);
            }
        });
        return call;
    }

post、put、delete帶參請求:

/**
     * 有參連線
     * @param type
     * @param url
     * @param map
     * @param callback
     */
    private static Call<String> connect(int type, String url, Map<String, Object> map, final RetrofitCallBack callback) {
//        FormBody.Builder builder = new FormBody.Builder();
//        for (Map.Entry<String, Object> entry : map.entrySet()) {
//            String key = entry.getKey();
//            Object value = entry.getValue();
//            builder.add(key, value.toString());
//            Log.d("params--", "key:" + key + "     value:" + value);
//        }
        //補充一下,上面是預設的表單提交,下面是form-data,分別放到兩個方法中,一個用於帶檔案引數的,一個用於不帶檔案的,當然也可以和後臺協商,統一用一種規則。

        MultipartBody.Builder builder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value.getClass().getName().equals("java.io.File")) {
                File file = (File) value;
                builder.addFormDataPart(key, file.getName(), RequestBody.create(MediaType.parse("application/octet-stream"), file));
                Log.d("params--","key:"+ key + "---value:"+file.getPath());
            } else {
                builder.addFormDataPart(key, value.toString());
                Log.d("params--","key:"+ key + "---value:"+value);
            }
        }







        RequestBody requestBody = null;
        try {
            requestBody = builder
                    .build();
        } catch (Exception e) {
            e.printStackTrace();
            callback.onException(e);
        }
        Call<String> call = null;
        switch (type) {
            case POST_REQUEST:
                call = getInstance().postRequest(url, requestBody);
                break;
            case PUT_REQUEST:
                call = getInstance().putRequest(url, requestBody);

                break;
            case DELETE_REQUEST:
                call = getInstance().deleteRequest(url, requestBody);
                break;
        }
        call.enqueue(new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, Response<String> response) {

                callback.onSuccess(response, call);
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                callback.onFailure(call, t);
            }
        });
        return call;
    }

有些東西以後再擴充套件了,暫時就這些。

2017、6、5編輯:
這兩天用delete請求遇到BUG,說什麼引數啥啥啥的,無參沒問題,有參會報錯,先記著,以後再處理。