对Volley开源框架 进行封装

ygp8 8年前

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