对Volley Google I/O开源框架 进行封装

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. 图片过大,导致内存溢出等,需设置图片一级、二级缓存问题。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值