天天看點

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,說什麼參數啥啥啥的,無參沒問題,有參會報錯,先記着,以後再處理。

繼續閱讀