對Volley開源框架 進行封裝

ygp8 9年前發布 | 17K 次閱讀 Volley Android開發 移動開發

Volley是Ficus Kirpatrick在Gooogle I/O 2013發布的一個處理和緩存網絡請求的庫,能使網絡通信更快,更簡單,更健壯。
Volley名稱的由來: a burst or emission of many things or a large amount at once。
該框架適用于大部分app應用,其特點在與方便頻繁與網絡交互,如:圖片加載,json解析等。

筆者對其進行封裝,使其在項目中能更加方便和實用,大大開發效率。使之能一句話加載網絡圖片,一句話解析json 。


首先需要clone下來Volley的源碼。


我們來看一下源碼 volley.java

/*
     * Copyright (C) 2012 The Android Open Source Project
     *
     * Licensed under the Apache License, Version 2.0 (the "License");
     * you may not use this file except in compliance with the License.
     * You may obtain a copy of the License at
     *
     *      http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS,
     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     * See the License for the specific language governing permissions and
     * limitations under the License.
     */

    package com.android.volley.toolbox;
    import android.content.Context;
    import android.content.pm.PackageInfo;
    import android.content.pm.PackageManager.NameNotFoundException;
    import android.net.http.AndroidHttpClient;
    import android.os.Build;

    import com.android.volley.Network;
    import com.android.volley.RequestQueue;

    import java.io.File;

    public class Volley {

        /** Default on-disk cache directory. */
        private static final String DEFAULT_CACHE_DIR = "volley";

        /**
         * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
         *
         * @param context A {@link Context} to use for creating the cache dir.
         * @param stack An {@link HttpStack} to use for the network, or null for default.
         * @return A started {@link RequestQueue} instance.
         */
        public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
            File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

            String userAgent = "volley/0";
            try {
                String packageName = context.getPackageName();
                PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
                userAgent = packageName + "/" + info.versionCode;
            } catch (NameNotFoundException e) {
            }
            if (stack == null) {
                //用HttpUrlConnection 處理http請求
                if (Build.VERSION.SDK_INT >= 9) {
                    stack = new HurlStack();
                } else {
                    // Prior to Gingerbread, HttpUrlConnection was unreliable.用HttpClient處理網絡請求
                    // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
                    stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
                }
            }

            //構建一個字節池
            Network network = new BasicNetwork(stack);
            RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
            queue.start();

            return queue;
        }

        /**
         * Creates a default instance of the worker pool and calls {@link RequestQueue#start()} on it.
         *
         * @param context A {@link Context} to use for creating the cache dir.
         * @return A started {@link RequestQueue} instance.
         */
        public static RequestQueue newRequestQueue(Context context) {
            return newRequestQueue(context, null);
        }
    }




對Volley中訪問網絡的Request進行封裝  NetContext.java

package com.cn.framework.net;

    import android.content.Context;
    import android.widget.ImageView;

    import com.android.volley.RequestQueue;
    import com.android.volley.toolbox.ImageLoader;
    import com.android.volley.toolbox.ImageLoader.ImageCache;
    import com.android.volley.toolbox.ImageLoader.ImageContainer;
    import com.android.volley.toolbox.ImageLoader.ImageListener;
    import com.android.volley.toolbox.Volley;
    /**
     * 使用NetContext來訪問網絡,NetContext底部使用Volley作為通信框架
     */
    public class NetContext {
        /** 上下文  */
        private Context context;

        /** 圖片請求隊列  */
        private RequestQueue imageRequestQueue;

        /** json請求隊列  */
        private RequestQueue jsonRequestQueue;

        /** 圖片ImageLoader */
        private ImageLoader imageLoader;

        /** 圖片以及緩存LRU */
        private ImageCache imageCache;

        /** LRU緩存的數量,為了防止內存溢出,一般不要超過60 */
        private static final int LRU_CACHE_SIZE = 20;

        private static NetContext instance = null;


        /**
         * 構造函數
         * 
         * @param context android應用上下文
         */
        private NetContext(Context context){
            this.context = context;
            this.jsonRequestQueue = Volley.newRequestQueue(context);

            this.imageRequestQueue = Volley.newRequestQueue(context);
            this.imageCache = new BitmapCache(LRU_CACHE_SIZE);
            this.imageLoader = new ImageLoader(imageRequestQueue, imageCache);
        }

        /**
         * 單例模式
         * 
         * @param context
         * @return NetUtil
         */
        public static NetContext getInstance(Context context){
            if (instance == null) {
                synchronized (NetContext.class) {
                    if (instance == null) {
                        instance = new NetContext(context);
                    }
                }
            }
            return instance;
        }
        /**
         * 得到圖片加載器
         * 
         * @return ImageLoader
         */
        public ImageLoader getImageLoader() {
            return imageLoader;
        }

        /**
         * 得到json的請求隊列
         * @return RequestQueue
         */
        public RequestQueue getJsonRequestQueue() {
            return jsonRequestQueue;
        }
    }




NetUtil.java 類 ,一句話解析Json,一句話加載網絡圖片



package com.cn.framework.util;

    import org.json.JSONArray;
    import org.json.JSONObject;

    import android.content.Context;
    import android.widget.ImageView;

    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.toolbox.ImageLoader;
    import com.android.volley.toolbox.ImageLoader.ImageContainer;
    import com.android.volley.toolbox.ImageLoader.ImageListener;
    import com.android.volley.toolbox.JsonArrayRequest;
    import com.android.volley.toolbox.JsonObjectRequest;
    import com.kuaidian.framework.net.NetContext;

    public class NetUtil {
        /**
         * 防止工具類被實例化
         */
        private NetUtil(){
            throw new AssertionError();
        }

        /**
         * 加載圖片
         * 
         * @param context android應用上下文
         * @param imageUrl 請求的圖片url
         * @param view 展示圖片的view
         * @param defaultImageResId 加載過程中的默認圖片資源Id,如果沒有則為0
         * @param errorImageResId 加載過程中的錯誤圖片資源Id,如果沒有則為0
         * @return ImageContainer 圖片請求和結果
         */
        public static ImageContainer loadImage(Context context, String imageUrl, ImageView view, int defaultImageResId, int errorImageResId){
            NetContext netContext = NetContext.getInstance(context);
            ImageListener imgListener = ImageLoader.getImageListener(view, defaultImageResId, errorImageResId);
            return netContext.getImageLoader().get(imageUrl, imgListener);
        }

        /**
         * 以GET或者POST方式發送jsonObjectRequest
         * 
         * @param context android應用上下文
         * @param requestUrl 請求的Url
         * @param requestParameter 請求的參數,如果為null,則使用GET方法調用,否則使用POST方法調用
         * @param listener 正確返回之后的lisenter
         * @param errorListener 錯誤返回的lisenter
         */
        public static void sendJsonObjectRequest(Context context, String requestUrl, JSONObject requestParameter, Listener<JSONObject> listener,
                ErrorListener errorListener){
            JsonObjectRequest request = new JsonObjectRequest(requestUrl, requestParameter, listener, errorListener);
            NetContext netContext = NetContext.getInstance(context);
            netContext.getJsonRequestQueue().add(request);
        }

        /**
         * 以GET方式發送jsonArrayRequest
         * 
         * @param context android應用上下文
         * @param requestUrl 請求的Url
         * @param listener 正確返回之后的lisenter
         * @param errorListener 錯誤返回的lisenter
         */
        public static void sendJsonArrayRequest(Context context, String requestUrl, Listener<JSONArray> listener,
                ErrorListener errorListener){
            JsonArrayRequest request = new JsonArrayRequest(requestUrl,listener, errorListener);
            NetContext netContext = NetContext.getInstance(context);
            netContext.getJsonRequestQueue().add(request);
        }
    }



Json解析接口 JsonParserInterface.java

package com.cn.framework.jsonparseinterface;
    import org.json.JSONObject;

    /**
     * jsonResonse的解析接口
     */
    public interface JsonParserInterface<T> {
        /**
         * @param result 返回的結果 
         * @param response 網絡傳遞進來的response
         */
        void parseJson(T result,JSONObject response);
    }



Json數據解析 PaperParser.java

package com.cn.framework.jsonparseimpl;

    import java.util.List;
    import org.json.JSONArray;
    import org.json.JSONObject;

    import com.kuaidian.framework.entity.Paper;
    import com.kuaidian.framework.jsonparseinterface.JsonParserInterface;

    public class PaperParser implements JsonParserInterface<List<Paper>> {

        private static PaperParser instance = null;
        private PaperParser(){}
        public synchronized static PaperParser getInstance(){
            if (instance == null) {
                instance = new PaperParser();
            }
            return instance;
        }

        @Override
        public void parseJson(List<Paper> list, JSONObject response) {
            try {
                JSONArray jsonArray = (JSONArray) response.get("data");
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject object = (JSONObject) jsonArray.get(i);
                    int id = object.getInt("id");
                    String smallPic = object.getString("smallPic");
                    String title = object.getString("layoutpage");
                    String bigPic = object.getString("bigPic");
                    Paper newspaper = new Paper();
                    newspaper.setId(id);
                    newspaper.setSmallPic(smallPic);
                    newspaper.setLayoutpage(title);
                    newspaper.setQi(periodId);
                    newspaper.setBigPic(bigPic);
                    list.add(newspaper);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }   
        }
    }



解析Json時所需要用到的實體類 Paper.java


package com.cn.framework.entity;

    import java.util.Date;

    public class Paper {

        private int id;
        private Date date;
        private String bigPic;
        private String smallPic;
        private String bm;
        private String layoutpage;

        public Paper() {
        }

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public String getBigPic() {
            return bigPic;
        }

        public void setBigPic(String bigPic) {
            this.bigPic = bigPic;
        }

        public String getSmallPic() {
            return smallPic;
        }

        public void setSmallPic(String smallPic) {
            this.smallPic = smallPic;
        }

        public String getBm() {
            return bm;
        }

        public void setBm(String bm) {
            this.bm = bm;
        }

        public String getLayoutpage() {
            return layoutpage;
        }

        public void setLayoutpage(String layoutpage) {
            this.layoutpage = layoutpage;
        }

        @Override
        public String toString() {
            return "Newspaper [id=" + id + ", date=" + date + ", bigPic=" + bigPic
                    + ", smallPic=" + smallPic + ", bm=" + bm
                    + ", layoutpage=" + layoutpage + "]";
        }

    }




MainActivity.java中使用:


package com.cn.framework;

    import java.util.ArrayList;
    import java.util.List;
    import org.json.JSONObject;

    import android.app.Activity;
    import android.os.Bundle;
    import android.widget.ImageView;

    import com.android.volley.Response.ErrorListener;
    import com.android.volley.Response.Listener;
    import com.android.volley.VolleyError;
    import com.example.kuaidianframework.R;
    import com.kuaidian.framework.entity.Paper;
    import com.kuaidian.framework.jsonparseimpl.PaperParser;
    import com.kuaidian.framework.util.LogUtil;
    import com.kuaidian.framework.util.NetUtil;

    public class MainActivity extends Activity {

        private ImageView imageView;
        private List<Paper> papers = new ArrayList<Paper>();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            imageView = (ImageView) findViewById(R.id.imageView);
            testJsonRequest();
            testImageRequset();
        }

        //解析Json數據
        private void testJsonRequest(){
            String requestUrl = "http://42.51.16.158:8080/dsqy/action/phoneManager_getNewPaperByQi?type=1";
            NetUtil.sendJsonObjectRequest(this, requestUrl, null, new Listener<JSONObject>(){
                @Override
                public void onResponse(JSONObject response) {
                    PaperParser newsPaperParser = PaperParser.getInstance();
                    //此處傳入papers對象,就將數據存在該對象中
                    newsPaperParser.parseJson(papers, response);

                    for (int i = 0; i < papers.size(); i++) {
                        LogUtil.info(MainActivity.class, papers.get(i).getBigPic());
                    }
                }

            }, new ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    //TODO
                }
            });
        }

        //顯示網絡圖片
        private void testImageRequset(){
            //String imageUrl = "http://www.iqianyan.cc/simg/20140119/s_20140119195840.jpg";
            String imageUrl = "http://b.hiphotos.baidu.com/pic/w%3D310/sign=9b24260fd53f8794d3ff4e2fe21a0ead/f636afc379310a55ba781b43b64543a98226102c.jpg";
            NetUtil.loadImage(this, imageUrl, imageView, R.drawable.ic_launcher, 0);
        }
    }



到此運行你的應用,有沒有發現方便快捷了不少呢,解析json,加載顯示網絡圖片,只需要一行代碼就可以。

不過在開發過程中也需要考慮到一些問題,比如:

1. 當圖片過多過大時,在ListView中滾動圖片錯位的問題。

2. 圖片過大,導致內存溢出等,需設置圖片一級、二級緩存問題。

來自:http://blog.csdn.net/gao_chun/article/details/34117083

 本文由用戶 ygp8 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!