介面回調封裝

来源:http://www.cnblogs.com/dingzq/archive/2016/10/24/5992412.html
-Advertisement-
Play Games

在開發的過程中,關於對請求回調數據的處理以及消息提示,我發現了兩個問題: 1.別人都怎麼做的我不知道,但是我看到的,很多人在寫網路請求的時候,不管是自己直接寫的,或者還是直接使用第三方網路框架,在拿到數據的時候,一般都是自己根據返回的數據中,使用約定好的key去解析自己需要的數據,直接使用或者轉換成 ...


  

 

  在開發的過程中,關於對請求回調數據的處理以及消息提示,我發現了兩個問題:

  1.別人都怎麼做的我不知道,但是我看到的,很多人在寫網路請求的時候,不管是自己直接寫的,或者還是直接使用第三方網路框架,在拿到數據的時候,一般都是自己根據返回的數據中,使用約定好的key去解析自己需要的數據,直接使用或者轉換成javaBean、數組。話說,這樣很麻煩不是嗎,每一次請求數據就要去解析一次,不同的頁面,那得重覆寫多少代碼,而且看起來也比較亂。

  2.很多時候 ,數據請求成功或者失敗,總要給用戶一個簡短的提示。提示什麼樣的文案和什麼情況下需要提示,這也是個比較麻煩的問題。

  為此,我對請求回調進行了封裝,代碼結構清晰了很多,而且也比較好用,主要做到了以下功能:

  1.如果返回的數據是javaBean或者數組Array,只需要在請求時,在請求時的CallBack傳遞對應的數據類型和JavaBean.class,這樣數據成功回調後,就可以把返回的Object 對象直接轉換成對應的 JavaBean.class 實體對象或者 Array 對象。當然,如果返回的只是簡單的數據類型的話,什麼都不需要設置就可以了,直接使用返回的 String data 即可。

  2.不管回調成功還是失敗,統一彈出提示的話,直接在請求時的CallBack中傳遞個Context 對象;不需要提示則不傳;想自己定製提示內容,則不傳,併在CallBack 中對應的 onSuccess、onFailure方法中,彈出自己想要的內容。

 

  廢話不多說了,直接上代碼~

 

  一、消息提不提示的問題,我以獲取驗證碼介面為例。

1.不主動彈出提示消息提示。

a.發起請求

ApiClient.getVerificationCode(phone,new VerificationCodeCallback());

b.數據回調

// 獲取驗證碼回調
    public class VerificationCodeCallback extends ApiUiCallback {

        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);
           
        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                // TODO
            }
        }
    }

想自己定製提示內容,在CallBack 中對應的 onSuccess、onFailure方法中,彈出自己想要的內容即可。

 

2.主動彈出提示消息提示。

a.發起請求

ApiClient.getVerificationCode(phone,new VerificationCodeCallback(this));

b.數據回調

// 獲取驗證碼回調
    public class VerificationCodeCallback extends ApiUiCallback {
        public VerificationCodeCallback(Context context) {
            super(context);
        }

        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);
           
        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                // TODO
            }
        }
    }

 

主動彈出的話,需要在回調類中 實現構造方法 VerificationCodeCallback(Context context),併在使用的時候傳遞個Context。

 

 二、數據返回Array或者 單一 JavaBean 問題

  方法說明:

setOutClass()中傳遞的是數組中的數據實體類。
setResponseTypeEnum()中傳遞的是數據的類型 單個JavaBean 還是 Array

1. 返回 Array

a.發起請求

        ApiClient.openCityList(new OpenCityListCallback().setOutClass(String.class).setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_ARRAY));

b.數據回調

public class OpenCityListCallback extends ApiUiCallback {
        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);
            showToast(R.string.network_anomaly);
        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (outDo instanceof List) {
                List<String> list = (List<String>) outDo;
                // TODO
            } else {
                showToast(resultInfo);
            }
        }

    }

 

2. 返回 單一 JavaBean 

a.發起請求

        ApiClient.checkNewVersion(new CheckNewVersionCallback().setResponseTypeEnum(ResponseTypeEnum.JSON_ORIGINAL_RESULT_BEAN).setOutClass(UpdateInfo.class));

 

b.數據回調

 

public class CheckNewVersionCallback extends ApiUiCallback {
        @Override
        public void onFailure(HttpException e, String s) {
            super.onFailure(e, s);

        }

        @Override
        public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {
            super.onSuccess(data, resultCode, resultInfo, outDo);
            if (resultCode == 0) {
                if (outDo instanceof UpdateInfo) {
                    updateInfo = (UpdateInfo) outDo;
                    // TODO
                }
            }
        }
    }

 

  二話不說上源碼!!!!

1. 主要的目錄結構

 

 2.  ApiConstant.class

/**
 * Created by ding on 2016/9/26
 */
public class ApiConstant {

    /**
     * 字元集:UTF-8
     */
    public static final String CHARSET_UTF8 = "UTF-8";
    /**
     * 預設字元集
     */
    public static final String DEFUALT_CHARSET = CHARSET_UTF8;
}

 3.  ResponseTypeEnum.class

/**
 * 返回數據類型常量
 * Created by ding on 2016/9/26.
 */
public enum ResponseTypeEnum {

    /**
     * JSON格式字元串;
     * 基本類型按JSON格式原樣輸出;
     * data內容封裝到Result對象的data屬性,再輸出JSON格式字元串;
     * data是普通JavaBean;
     */
    JSON_ORIGINAL_RESULT_BEAN("json_orig_result", true, false),
    /**
     * JSON格式字元串;
     * 基本類型按JSON格式原樣輸出;
     * data內容封裝到Result對象的data屬性,再輸出JSON格式字元串;
     * data是JsonArray集合;
     */
    JSON_ORIGINAL_RESULT_ARRAY("json_orig_result", true, true),

    /**
     * 原生字元串;
     */
    STRING("string", false, false);

    private String rtType;//返回數據類型
    private boolean isJson;//返回數據是否JSON格式
    private boolean isArray;//返回數據是否JSON集合

    private ResponseTypeEnum(String rtType, boolean isJson, boolean isArray) {
        this.rtType = rtType;
        this.isJson = isJson;
        this.isArray = isArray;
    }

    public String getRtType() {
        return rtType;
    }

    public boolean isArray() {
        return isArray;
    }

    public boolean isJson() {
        return isJson;
    }
}

 

4.  ApiConvert.class

/**
 * Created by ding on 2016/9/26
 *convert層轉換工具類
 * 提供jsonData 和outputDo的轉換方法
 */
public class ApiConvert {

    private static final String TAG = "api.ApiConvert";


    /**
     * 將json格式的byte數組數據轉換為業務JavaBean實例對象
     *
     * @param jsonData JSON格式的String字元串
     * @param outClass 業務JavaBean的類信息
     * @return Object outClass對應的業務JavaBean實例對象
     */
    public static Object jsonToOutputDO(String jsonData, ResponseTypeEnum responseType, Class<?> outClass) {
        if ((outClass == null) || TextUtils.isEmpty(jsonData)) {
            LogUtil.LogE(ApiConvert.class, "outClass is null or jsonData is blank.");
            return null;
        }

        try {
            if ((responseType != null) && responseType.isJson()) {
                if (responseType.isArray()) {
                    return JSON.parseArray(jsonData, outClass);
                } else {
                    return JSON.parseObject(jsonData, outClass);
                }
            } else {
                return jsonData;
            }
        } catch (Throwable e) {
            LogUtil.LogE(ApiConvert.class, "[jsonToOutputDO]invoke JSON.parseObject error.");
        }
        return null;
    }

}

 

5.  ApiUiCallback.class

 

/**
 * Created by ding on 2016/9/26.
 */
public abstract class ApiUiCallback extends RequestCallBack<String> {

    protected Context mContext = null;
    private ResponseTypeEnum responseTypeEnum = null;
    private Class<?> outClass = null;
    private String reqContent;//

    public ApiUiCallback() {
        this.mContext = null;
    }

    public ApiUiCallback(Context context) {
        this.mContext = context;
    }


    public ApiUiCallback(int rate) {
        super(rate);
        this.mContext = null;
    }

    public ApiUiCallback(Object userTag) {
        super(userTag);
        this.mContext = null;
    }

    public ApiUiCallback(int rate, Object userTag) {
        super(rate, userTag);
        this.mContext = null;
    }

    public ApiUiCallback setResponseTypeEnum(ResponseTypeEnum responseTypeEnum) {
        this.responseTypeEnum = responseTypeEnum;
        return this;
    }

    public ApiUiCallback setOutClass(Class<?> outClass) {
        this.outClass = outClass;
        return this;
    }

    public ApiUiCallback setReqContent(String reqContent) {
        this.reqContent = reqContent;
        return this;
    }

    public String getReqContent() {
        return reqContent;
    }

    @Override
    public void onSuccess(ResponseInfo<String> responseInfo) {
        String json = CommonUtil.fromtoJson(responseInfo.result);
        LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onSuccess");
        if (null != json) {
            JSONObject object = JSON.parseObject(json,
                    JSONObject.class);
            int resultCode = object.getInteger("resultCode");
            String resultInfo = object.getString("resultInfo");
            String jsonData = object.getString("data");
            if (mContext != null) {
                ToastTools.showToast(mContext, resultInfo);
            }
            Object outDO = ApiConvert.jsonToOutputDO(jsonData, responseTypeEnum, outClass);
            onSuccess(jsonData, resultCode, resultInfo, outDO);
        }
    }

    public void onSuccess(String data, int resultCode, String resultInfo, Object outDo) {


    }

    @Override
    public void onFailure(HttpException e, String s) {
        LogUtil.LogE(ApiUiCallback.class, "ApiUiCallback--->onFailure");
        if (mContext != null) {
            ToastTools.showToast(mContext, "請求失敗");
        }
    }
}

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡多謝某童鞋的提醒!說我的上篇隨筆jquery插件開發的方式一還還可用於合併參數和深clone,雖然方式二中用了方式一做參數合併,但並未詳細介紹,所以今天在此處做點補充! 一、合併參數 jquery的extend擴展原型: 返回值未arg1,arg2……合併到arg。這裡就有兩種用法。 省略arg ...
  • avalon.js是一款迷你的MVVM框架,設計者將其相容到了IE6。輕巧的體積和良好的相容使它非常適合國內的某些項目(學校、政府、銀行)。然而有時候居然出現了在ie上無法渲染的情況。 例如下列這段簡單的demo: 在chrome上的顯示是: 而在ie8上顯示卻是這樣: 大家不要慌張,可能是你加入了 ...
  • 一,JS模塊化演變過程 1.普通函數封裝 最初的這種普通函數封裝的缺點很明顯:污染了全局變數,無法避免的會與其他模塊發生變數名衝突,而且自身模塊成員之間沒有任何聯繫,,說白了就是沒有做到“高內聚,低耦合”原則 2.對象 技術一直在進步,這種做法的避免了變數污染,只要保證模塊名唯一即可,自身模塊內的成 ...
  • 所謂彈性滾動就是指在翻動長頁面手指離開時,有由慢到塊,由快到慢的過度。 安卓平臺上的大多數瀏覽器都預設了該行為 ios當前還只對<body>下的 overflow 預設產生彈性滾動效果 前一陣子做了一個手機官網,用到了 <div> 中的 overflow,再調試 ios 中遇到了彈性滾動的問題: i ...
  • javascript的一切實例都是對象,只是對象之間稍有不同,分為基本類型和引用類型。 基本類型對象指的是字元串(String)、數值(Number)、布爾值(Boolean),引用類型對象指的是數組(Array)、對象(Object)、函數(Function)。 這兩類數據的引用有差別。普通對象存 ...
  • /** * 獲取程式包名(本程式包名5.0版本上下都可獲取) * * @return */ public String getTaskPackname() { ActivityManager.RunningAppProcessInfo currentInfo = null; Field field  ...
  • 蘋果在iOS 10開放了系統電話許可權,全新的Callkit框架能夠讓音視頻的第三方應用獲得系統級的通話體驗,本次分享將主要介紹如何應用Callkit框架和一些適配經驗。 ...
  • 這裡是Android性能優化典範第6季的課程學習筆記,從被@知會到有連載更新,這篇學習筆記就一直被惦記著,現在學習記錄分享一下,請多多指教包涵!這次一共才6個小段落,涉及的內容主要有:程式啟動時間性能優化的三個方面:優化activity的創建過程,優化application對象的啟動過程,正確使用啟... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...