Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> volley框架介紹

volley框架介紹

編輯:關於Android編程

volley介紹

開發android應用很多時候都要涉及網絡操作,Android SDK中提供了HttpClient 和 HttpUrlConnection兩種方式用來處理網絡操作,但當應用比較復雜的時候需要我們編寫大量的代碼處理很多東西:圖像緩存,請求的調度等等;

而Volley框架就是為解決這些而生的,它與2013年Google I/O大會上被提出:使得Android應用網絡操作更方便更快捷;抽象了底層Http Client等實現的細節,讓開發者更專注與產生RESTful Request。另外,Volley在不同的線程上異步執行所有請求而避免了阻塞主線程。

目前的HTTP通信框架,AsyncHttpClient,網絡圖片加載框架,Universal-Image-Loader,而Volley是將以上兩個框架集於一身。

這裡寫圖片描述

volley下載

git clone https://android.googlesource.com/platform/frameworks/volley  

或者使用我的地址,很久沒有更新了,請見諒,解決了SSL證書問題以及做了簡單的緩存

volley特點

自動調度網絡請求 多個並發的網絡連接 通過使用標准的HTTP緩存機制保持磁盤和內存響應的一致 支持請求優先級 支持取消請求的強大API,可以取消單個請求或多個 易於定制 健壯性:便於正確的更新UI和獲取數據 包含調試和追蹤工具

volley使用

我一般都是使用封裝好的方法

創建volleyHttpClient對象

封裝了返回Gson和String的get,post請求以及相應需要增加oauth驗證的方法

public class VolleyHttpClient {

    public static final int GET = 1;

    public static final int GET_AOUTH = 2;

    public static final int POST = 3;

    public static final int POST_AOUTH = 4;

    public static final int GETSTRING = 5;

    public static final int GETSTRING_AOUTH = 6;

    public static final int POSTSTRING_AOUTH = 7;

    private static final String TAG = "VolleyHttpClient";

    private static HttpService httpService;
    private final static Gson gson = new Gson();

    private static BaseActivity activity;


    public VolleyHttpClient(HttpService httpService) {
        this.httpService = httpService;
    }

    /**
     * 傳入初始化好的httpService 實例
     *
     * @param httpService
     * @return
     */
    public static VolleyHttpClient newInstance(HttpService httpService, Context context) {
        activity = (BaseActivity) context;
        if (httpService != null) {
            return new VolleyHttpClient(httpService);
        }
        return null;
    }

    public void post(ApiRequest apiRequest) {
        doNetTask(POST, apiRequest, DataCacheType.NO_CACHE);
    }

    public void postWithOAuth(ApiRequest apiRequest) {
        doNetTask(POST_AOUTH, apiRequest, DataCacheType.NO_CACHE);
    }

    public void get(ApiRequest apiRequest) {
        doNetTask(GET, apiRequest, DataCacheType.NO_CACHE);
    }

    public void getWithOAuth(ApiRequest apiRequest) {
        doNetTask(GET_AOUTH, apiRequest, DataCacheType.NO_CACHE);
    }

    public void doNetTask(int method, ApiRequest apiRequest) {
        doNetTask(method, apiRequest, DataCacheType.NO_CACHE);
    }

    public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType) {
        doNetTask(method, apiRequest, cacheType, false, null);
    }


    public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType,
                          boolean needLogin, BaseActivity activity) {
        doNetTask(method, apiRequest, cacheType, needLogin, activity, false);
    }


    public void doNetTask(int method, ApiRequest apiRequest, DataCacheType cacheType,
                          boolean needLogin, BaseActivity activity, boolean needFinish) {
        if (needLogin && activity.app.getUserParam() == null) {
            try {
                activity.cancelLoadingDialog();
            } catch (Exception e) {
                e.printStackTrace();
            }
            Intent intent = new Intent(activity, LoginActivity_.class);
            activity.startActivity(intent);
            if (needFinish) {
                activity.finish();
            }
            return;
        }
        switch (method) {
            case GET:
                //USER_OLD_CACHE有緩存先加載緩存數據,然後網絡請求只是保存數據
                //TEMP_CACHE有緩存先加載緩存數據,不進行網絡請求
                get(apiRequest, false, cacheType);
                break;
            case GET_AOUTH:
                get(apiRequest, true, cacheType);
                break;
            case POST:
                post(apiRequest, false, cacheType);
                break;
            case POST_AOUTH:
                post(apiRequest, true, cacheType);
                break;
            case GETSTRING:
                getByStringRequest(apiRequest, false, cacheType);
                break;
            case GETSTRING_AOUTH:
                getByStringRequest(apiRequest, true, cacheType);
                break;
            case POSTSTRING_AOUTH:
                postByStringRequest(apiRequest, true, cacheType);
                break;
        }
    }


    /**
     * 不用傳header以及accesstoken的GET請求
     *
     * @param apiRequest
     */
    public void get(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) {


        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        if (needOauth) {

            String accessToken = GlobalPhone.token;

            if(TextUtils.isEmpty(accessToken)){
                accessToken = DataCache.getDataCache()
                        .queryCache("access_token");
            }
            if (!TextUtils.isEmpty(accessToken)) {
                LogUtils.e("access_token", accessToken);
            }
//        header.put("Authorization", "Bearer" + " " + accessToken);
            header.put("token", accessToken);
        }
        String url = apiRequest.getUrl(Method.GET);
        Listener listener = apiRequest.getListener();
        LogUtils.e("------cacheType---------", cacheType.name());
        switch (cacheType) {
            case USE_OLD_CACHE:
            case TEMP_CACHE:
                String cacheStr ="";
                if(cacheType == DataCacheType.TEMP_CACHE){
                    cacheStr = DataCache.getDataCache().queryTempCache(url);
                }else {
                    cacheStr = DataCache.getDataCache().queryCache(url);
                }
                if (!TextUtils.isEmpty(cacheStr)) {
                    try {
                        if (apiRequest.getResponseType() != null) {
                            //有緩存先加載緩存數據
                            listener.onResponse(gson.fromJson(cacheStr, apiRequest.getResponseType()));
                            //有緩存先加載緩存數據,不進行網絡請求
                            if (cacheType == DataCacheType.TEMP_CACHE) {
                                return;
                            }
                        } else {
                            listener.onResponse(cacheStr);
                            if (cacheType == DataCacheType.TEMP_CACHE) {
                                return;
                            }
                        }

                    } catch (JsonSyntaxException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
        GsonRequest request = new GsonRequest(Method.GET, url,
                apiRequest.getResponseType(), header, null,
                listener, apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        //網絡錯誤並且使用TEMP_CACHE和use old cache還有待考察
        if (!useCache(apiRequest.getResponseType(), url, listener)) {
            httpService.addToRequestQueue(request);
        }

    }


    public void post(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) {

        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        if (needOauth) {
            String accessToken = GlobalPhone.token;

            if(TextUtils.isEmpty(accessToken)){
                accessToken = DataCache.getDataCache()
                        .queryCache("access_token");
            }
            if (!TextUtils.isEmpty(accessToken)) {
                LogUtils.e("access_token", accessToken);
            }
//        header.put("Authorization", "Bearer" + " " + accessToken);
            header.put("token", accessToken);
        }

        LogUtils.e("------cacheType---------", cacheType.name());
        String url = apiRequest.getUrl(Request.Method.POST);
        Listener listener = apiRequest.getListener();
        if (apiRequest.getParams() != null && apiRequest.getParams().size() > 0) {
            //post有參數時候請求不建議使用use_old_cache方式,因為根據路徑存儲,post參數不在路徑中
            if (cacheType == DataCacheType.USE_OLD_CACHE) {
                cacheType = DataCacheType.CACHE;
            }
        }
        switch (cacheType) {
            case USE_OLD_CACHE:
            case TEMP_CACHE:
                String cacheStr = DataCache.getDataCache().queryCache(url);
                if (!TextUtils.isEmpty(cacheStr)) {
                    try {
                        if (apiRequest.getResponseType() != null) {
                            //有緩存先加載緩存數據
                            listener.onResponse(gson.fromJson(cacheStr, apiRequest.getResponseType()));
                            //有緩存先加載緩存數據,不進行網絡請求
                            if (cacheType == DataCacheType.TEMP_CACHE) {
                                return;
                            }
                        } else {
                            listener.onResponse(cacheStr);
                            if (cacheType == DataCacheType.TEMP_CACHE) {
                                return;
                            }
                        }

                    } catch (JsonSyntaxException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
        GsonRequest request = new GsonRequest(Request.Method.POST, url,
                apiRequest.getResponseType(), header,
                apiRequest.getParams(), listener,
                apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        //網絡錯誤並且使用TEMP_CACHE和use old cache還有待考察
        if (!useCache(apiRequest.getResponseType(), url, listener)) {
            httpService.addToRequestQueue(request);
        }

    }

    /**
     * 圖片請求
     */
    public ImageLoader.ImageContainer loadingImage(ImageView imageView, String url, int loadingResid,
                                                   int errorResid, BitmapCache mCache, ImageLoader.ImageListener listener) {
        if (listener == null) {
            listener = ImageLoader.getImageListener(imageView,
                    loadingResid, errorResid);
        }
        if (httpService.httpQueue != null) {
            ImageLoader imageLoader = new ImageLoader(httpService.httpQueue,
                    mCache);
            return imageLoader.get(url, listener);
        }

        return null;
    }

    public void loadingImage(ImageView imageView, String url, int loadingResid,
                             int errorResid, BitmapCache mCache) {
        loadingImage(imageView, url, loadingResid, errorResid, mCache, null);
    }

    /**
     * StringRequest
     */

    public void getByStringRequest(ApiRequest apiRequest, boolean needOauth, DataCacheType cacheType) {
        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        if (needOauth) {
            String accessToken = GlobalPhone.token;

            if(TextUtils.isEmpty(accessToken)){
                accessToken = DataCache.getDataCache()
                        .queryCache("access_token");
            }
            if (!TextUtils.isEmpty(accessToken)) {
                LogUtils.e("access_token", accessToken);
            }
//        header.put("Authorization", "Bearer" + " " + accessToken);
            header.put("token", accessToken);
        }
        String url = apiRequest.getUrl(Request.Method.GET);
        Listener listener = apiRequest.getListener();

        StringRequest request = new StringRequest(Request.Method.GET, url,
                header, null, listener, apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        if (!useCache(null, url, listener)) {
            httpService.addToRequestQueue(request);
        }

    }

    /**
     * StringRequest
     */
    public void postByStringRequest(ApiRequest apiRequest,
                                    boolean needOauth, DataCacheType cacheType) {
        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        String url = apiRequest.getUrl(Request.Method.POST);
        Listener listener = apiRequest.getListener();

        if (needOauth) {
            String accessToken = GlobalPhone.token;

            if(TextUtils.isEmpty(accessToken)){
                accessToken = DataCache.getDataCache()
                        .queryCache("access_token");
            }
            if (!TextUtils.isEmpty(accessToken)) {
                LogUtils.e("access_token", accessToken);
            }
//        header.put("Authorization", "Bearer" + " " + accessToken);
            header.put("token", accessToken);
        }
        Map params = new HashMap();
        for (String key : apiRequest.getParams().keySet()) {
            params.put(key, (String) apiRequest.getParams().get(key));
        }
        StringRequest request = new StringRequest(Request.Method.POST, url,
                header, params, listener,
                apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        if (!useCache(null, url, listener)) {
            httpService.addToRequestQueue(request);
        }
    }

    /**
     * 斷網情況使用緩存處理
     *
     * @param clazz
     * @param url
     * @param listener
     * @return
     */
    private boolean useCache(Class clazz, String url, Listener listener) {
        HttpService.httpQueue.getCache().invalidate(url, true);
        if (!NetWorkUtils.detect(httpService.getContext())) {
            String cacheStr = DataCache.getDataCache().queryCache(url);
            if (cacheStr != null) {
                try {
                    if (clazz != null) {
                        listener.onResponse(gson.fromJson(cacheStr, clazz));
                    } else {
                        listener.onResponse(cacheStr);
                    }
                    return true;

                } catch (JsonSyntaxException e) {
                    e.printStackTrace();
                    return false;
                }
            }
            return false;
        } else {
            return false;
        }
    }

    public void getExtWithOAuth(com.core.api.event.request.Request apiRequest) {
        getExtWithOAuth(apiRequest, DataCacheType.NO_CACHE);
    }

    public void getExtWithOAuth(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) {
        String url = apiRequest.getUrl(Request.Method.GET) + "?" + apiRequest.httpParam.encodeParametersToString("UTF-8");
        Listener listener = apiRequest.getListener();

        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);

        String accessToken = GlobalPhone.token;

        if(TextUtils.isEmpty(accessToken)){
            accessToken = DataCache.getDataCache()
                    .queryCache("access_token");
        }
        header.put("token", accessToken);

        GsonRequestExt request = new GsonRequestExt(Request.Method.GET, url,
                apiRequest.getResponseType(), header,
                apiRequest.httpParam, listener,
                apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        if (!useCache(apiRequest.getResponseType(), url, listener)) {
            httpService.addToRequestQueue(request);
        }
    }


    public void getExt(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) {
        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        String url = apiRequest.getUrl(Request.Method.GET) + "?" + apiRequest.httpParam.encodeParametersToString("UTF-8");
        Listener listener = apiRequest.getListener();
        GsonRequestExt request = new GsonRequestExt(Request.Method.GET, url,
                apiRequest.getResponseType(), header,
                apiRequest.httpParam, listener,
                apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        if (!useCache(apiRequest.getResponseType(), url, listener)) {
            httpService.addToRequestQueue(request);
        }
    }


    public void postExt(com.core.api.event.request.Request apiRequest, DataCacheType cacheType) {
        Map header = new HashMap();
        if (apiRequest.getHeaders() != null) {
            header.putAll(apiRequest.getHeaders());
        }
        header.put("code", ApiSettings.VERSION_CODE);
        header.put("osType", ApiSettings.OSTYPE);
        String accessToken = GlobalPhone.token;

        if(TextUtils.isEmpty(accessToken)){
            accessToken = DataCache.getDataCache()
                    .queryCache("access_token");
        }

        if (!TextUtils.isEmpty(accessToken)) {
            header.put("token", accessToken);
        }

        String url = apiRequest.getUrl(Request.Method.POST);
        Listener listener = apiRequest.getListener();
        GsonRequestExt request = new GsonRequestExt(Request.Method.POST, url,
                apiRequest.getResponseType(), header,
                apiRequest.httpParam, listener,
                apiRequest.getErrorlistener(), cacheType);
        request.setShouldCache(false);
        if (!useCache(apiRequest.getResponseType(), url, listener)) {
            httpService.addToRequestQueue(request);
        }
    }

    // volley框架緩存
    // if (HttpService.httpQueue.getCache().get(url) != null) {
    // String cacheStr = new String(HttpService.httpQueue.getCache()
    // .get(url).data);
    //
    // if (cacheStr != null) {
    //
    // try {
    // listener.onResponse(cacheStr);
    //
    // } catch (JsonSyntaxException e) {
    // e.printStackTrace();
    // }
    //
    // return;
    // }
    //
    // }

}

使用

先創建基礎Request,所有Request的繼承他
public class ApiRequest {

    public String url = "";

    protected Map params = null;

    private Class clazz;

    private Response.Listener listener;

    private Response.ErrorListener errorlistener;

    protected Map headers;

    public ApiRequest(String values, Class clazz) {
        this(values, clazz, false);
    }

    public ApiRequest(String values, Class clazz, boolean isChonggou) {
        if (isChonggou) {
            this.url = values;
        } else {
            this.url = String.format("%1$s%2$s", ApiSettings.URL_BASE, values);
        }
        this.clazz = clazz;
        this.params = new HashMap();
//        params.put("versionCode",ApiSettings.VERSION_CODE);
        this.headers = new HashMap();
    }


    public String getUrl(int method) {
        switch (method) {
            case Method.GET:
                return urlWithParameters(url, params);
            case Method.POST:
                return url;
        }
        return url;
    }

    public Map getParams() {
        if (params.isEmpty()) {
            Log.e("REQUEST_PARAMS", "null");
            return null;
        }
        return params;
    }

    public void setParams(Map params) {
        this.params = params;
    }

    public Class getResponseType() {
        return clazz;
    }

    public Response.Listener getListener() {
        return listener;
    }

    public void setListener(Response.Listener listener) {
        this.listener = listener;
    }

    public Response.ErrorListener getErrorlistener() {
        return errorlistener;
    }

    public void setErrorlistener(Response.ErrorListener errorlistener) {
        this.errorlistener = errorlistener;
    }

    public Map getHeaders() {
        if (headers.isEmpty()) {
            Log.e("REQUEST_Header", "null");
            return null;
        }
        return headers;
    }

    public void setHeaders(Map headers) {
        this.headers = headers;
    }

    public void addParams(Map params) {
        if (this.params != null) {
            this.params.putAll(params);
        } else {
            this.params = new HashMap();
            this.params.putAll(params);
        }
    }


    public static String urlWithParameters(String url,
                                           Map params) {
        StringBuilder builder = new StringBuilder();

        if (params != null) {
            for (HashMap.Entry entry : params.entrySet()) {
                if (builder.length() == 0) {
                    if (url.contains("?")) {
                        builder.append("&");
                    } else {
                        builder.append("?");
                    }
                } else {
                    builder.append("&");
                }
                builder.append(entry.getKey()).append("=")
                        .append(entry.getValue());
            }
        }

        return url + builder.toString();
    }


}

創建相應的request,ApiConstans中存放所有請求的路徑
public class AnswerListRequest extends ApiRequest implements ApiConstants {

    public AnswerListRequest(int page,int pageSize) {
        super(API_ANSWERLIST, AnswerListResponse.class);
        params.put("page",page);
        params.put("pageSize",pageSize);
    }
}

當然,所有請求可以放到一個library包,做抽離

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved