1. 程式人生 > >上門洗車APP --- Androidclient開發 之 網絡框架封裝介紹(二)

上門洗車APP --- Androidclient開發 之 網絡框架封裝介紹(二)

glob imp success rgb sed error margin p s 再次

上門洗車APP --- Androidclient開發 之 網絡框架封裝介紹(二)
前幾篇博文中給大家介紹了一下APP中的基本業務及開發本項目使用的網絡架構:

上門洗車APP --- Androidclient開發 前言及業務簡單介紹

上門洗車APP --- Androidclient開發 之 網絡框架封裝介紹(一)


本篇接著給大家分享網絡框架封裝。相信感興趣的朋友已經對上篇博文中的一些開源項目有了些許了解。這裏繼續為大家介紹關於GenericDataManager 通用網絡管理類中的 dataRequest 方法 和 請求參數封裝類 RequestParameterFactory

在上篇博文中我們有介紹

dataRequest 中傳入了一些參數,且使用了泛型<T>,以下就給大家介紹傳入的詳細參數:

/** 
     * 該方法封裝了網絡數據請求和數據解析 
     * 並傳入回調接口 
     * @param requestId     請求ID 
     * @param requestType   請求類型(此處依據傳入的常量僅僅提供了get請求和post請求) 
     * @param urlString     請求URL 
     * @param mParams       請求參數 
     * @param parser        通用數據解析抽象解析器 
     * @param mCallback     自己定義接口回調 
     */  
public <T> void dataRequest(final int requestId,String requestType,String urlString,RequestParams mParams,  
            final AbstractParser<T> mParser,final IRequestCallback mCallback)

這裏主要給大家說明兩個參數,即 final AbstractParser<T> mParser final IRequestCallback mCallback ,關於IRequestCallback 上篇已經介紹過。該類是定義的回調接口。該接口中的方法定義目的就是為了讓Activity實現做數據回調處理。

AbstractParser<T> 是個什麽玩意呢 ?


這裏先說一下項目中server傳遞過來的 JSON 數據格式,本著規範易讀,維護性好,管理方便的原則,我們統一了JSON格式,例如以下圖一、圖二中的介紹:

技術分享

圖 一



技術分享

圖 二

也就是說數據格式中的 messagestatusdata 三個字段是固定的。message為String類型。status為int類型,而data呢。有可能是jsonObject
者jsonArray,故每從server端發出一條請求,若請求成功,則返回格式都如上圖二所看到的,數據在data中。

所以此處我們定義一個model,即Result<T>類,來看下:

/**
 * @author gao_chun
 *
 */
public class Result<T> {

    private int status;//server返回狀態碼
    private String message;//message
    private T data;//返回數據

    /**
     * @return the status
     */
    public int getStatus() {

        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(int status) {

        this.status = status;
    }

    /**
     * @return the message
     */
    public String getMessage() {

        return message;
    }

    /**
     * @param message the message to set
     */
    public void setMessage(String message) {

        this.message = message;
    }

    /**
     * @return the data
     */
    public T getData() {

        return data;
    }

    /**
     * @param data the data to set
     */
    public void setData(T data) {

        this.data = data;
    }

    public boolean isOK() {
        return status >= 2000 && status < 3000;
    }
}

註:<T>。即泛型(Generic Types)。JDK1.5新特性,使用時能夠理解為創建一個用類型作為參數的類或方法。也能夠這樣理解,就是說,若一個類或方法裏面要用到另外一個類,但我又不確定所須要用到的那個類的詳細類型,所以就用到了Generic Types,這裏簡單說明,就只是多解釋了,朋友若不明確能夠去查閱相關文檔。


定義了一個model類,我們還再去定義一個解析器接口,即 IParser<T> ,該接口也使用泛型:

package org.gaochun.parser;

/**
 * @author gao_chun
 *
 */
public interface IParser<T> {

    public T parse(String data);

}

那麽以下我們再來看這個 AbstractParser<T> 類。這個類是我們定義的一個抽象解析類,且實現了解析器接口,須要註意的是我們定義的解析器 IParser<T> 使用了泛型,model類 Result<T> 也是如此,再次來看詳細的 AbstractParser<T>

import org.gaochun.model.Result;
import org.gaochun.utils.JsonUtils;
import org.json.JSONArray;
import org.json.JSONObject;

/**
 * 抽象解析類
 * 目的:解析server端外層數據,並供詳細解析類繼承重寫解析方法
 * @author gao_chun
 */
public abstract class AbstractParser<T> implements IParser<Result<T>> {

    @Override
    public final Result<T> parse(String response) {
	
        final Result<T> result = new Result<T>();	//創建Result類對象
		
        if (response != null && response.length() > 0) {
			
            final JSONObject jsonObject = JsonUtils.createJsonObject(response);	//將response的數據創建為JsonObject
			
            if (jsonObject != null) {
				//獲得status、message、data數據
                result.setStatus(JsonUtils.getStringInt(jsonObject, "status"));
                result.setMessage(JsonUtils.getString(jsonObject, "message"));
                final Object object = JsonUtils.getObject(jsonObject, "data");
				//實現data進一步解析。泛型
                if (object != null && (object instanceof JSONObject || object instanceof JSONArray)) {
                    T data = parseData(object);	//解析
                    result.setData(data);	//設置數據
                } else {
                    result.setData(null);
                }
            } else {
                result.setStatus(Result.STATUS_JSON_ERROR);
            }

        } else {
            result.setStatus(Result.STATUS_RESPONSE_NULL_OR_EMPTY);
        }
        return result;
    }

	//抽象解析方法,目的是為了讓詳細的解析類重寫
    protected abstract T parseData(Object object);
	
}

或許朋友就恍然大悟了,沃尼瑪。原來是醬紫的啊。


我們回過頭來看看登錄請求:

private void login(String name,String pwd){  

        GenericDataManager mDataManager = GenericDataManager.getInstance();//通用網絡管理類  
		
        RequestParams mParams = RequestParameterFactory.getInstance().login(name, pwd);//請求參數管理類  
		
        mDataManager.dataRequest(0,Constants.REQUEST.GET, RequestURL.URL_LOGIN, mParams,new ResultParser(), this);//運行網絡請求  
    }  
	

dataRequest 中傳入了 new ResultParser() 解析對象:

public class ResultParser extends AbstractParser<Object> {

    /* (non-Javadoc)
     * @see app.backend.network.AbstractParser#parseData(java.lang.Object)
     */
    @Override
    public Object parseData(Object object) {
        return object;
    }

這裏要說明。若server端 data 中無返回數據。也就是說發出請求,若僅僅須要告訴我 success 或者 failed,那就直接傳入new ResultParser() 解析器對象便可,在Activity的回調中,取出相應狀態推斷就可以:

技術分享


data 中存在返回數據須要解析。那麽此時須要創建解析器,給個樣例:

//繼承AbstractParser<T> 並在泛型中傳入解析後的結果(集合或對象)
public class WasherParser extends AbstractParser<List<NearbyWasher>> {

    @Override
    public List<NearbyWasher> parseData(Object object) {

        if (object != null) {
            return JSON.parseArray(object.toString(), NearbyWasher.class);
        }
        return null;
    }
}

JSON.parseArray() 方法是使用了阿裏巴巴的fastJson。此處大家也能夠使用Gson,或者使用Android自帶Json工具解析。

關於fastJson的使用,本人之前也總結了一篇博文可供大家參考。

Android開發之怎樣使用FastJson:http://blog.csdn.net/gao_chun/article/details/39232097

繼續給大家介紹 RequestParameterFactory ,該類的定義是封裝了參數請求,如:

技術分享

可能有朋友會說,直接寫在 private void login(String name,String pwd) 方法中不就能夠了,何必再創建一個類呢?

個人認為。這樣定義出一個類的話,有便於管理,若需求改變,添加了某個字段,不須要到處在Activity中尋找,且項目層次結構清晰。個人愚見。


這裏還須要給大家介紹一個類 GlobalConfigManager,該類為本地配置管理。主要作用是讀取serverip地址,比方我們的登錄接口是:http://192.168.1.1:8080/WashCar/washer/login?name=yang&pwd=123。我們將前綴http://192.168.1.1:8080 寫在AndroidManifest.xml文件的meta-data中,使用時在MainApplication中提前初始化:

    <application
        android:name="org.gaochun.ui.MainApplication"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/Theme.White.NoTitleBar" >

        <activity
            android:name="org.gaochun.activity.LoginActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

<!--serverIP-->
        <meta-data
            android:name="app.server"
            android:value="http://192.168.1.1:8080" />
    </application>

整個網絡通訊架構大概就是這麽回事了。整理了一下源代碼。給大家共享學習。

下篇博文打算給大家介紹res文件夾下界面開發中需註意的地方並共享源代碼,感謝大家的關註,共同學習。


源代碼下載:http://download.csdn.net/download/gao_chun/8843515



上門洗車APP --- Androidclient開發 之 項目結構介紹



【註:轉載註明gao_chun的BLOG http://blog.csdn.net/gao_chun/article/details/46655411

上門洗車APP --- Androidclient開發 之 網絡框架封裝介紹(二)