Android_开源框架_Volley实例
来源:互联网 发布:淘宝要绑定身份证号 编辑:程序博客网 时间:2024/06/06 07:12
本博文为子墨原创,转载请注明出处!
http://blog.csdn.net/zimo2013/article/details/16981945
由于博主的水平有限,如有误,请您帮助指正,共同学习,共同进步!
供初学者更好的理解和管理Volley!
(1).Android_开源框架_Volley(Google IO 2013)源代码及内部实现分析
(2).Android_开源框架_Volley实例
1.自定义相关类
在Android_开源框架_Volley(Google IO 2013)源代码及内部实现过程分析一文中,简单概述了Volley框架内部实现过程。如想理解彻底应该熟悉android多线程通信机制(Android_Thread多线程_Handler,Message,Looper,MessageQueue多线程和特殊UI更新一文) ,JDK1.5提供的java.util.concurrent相关并发库和http访问网络(Android_HttpURLConnection_Get和Post请求[该框架使用] / Android_HttpClient_get请求post表单提交上传 一文)及图片缓存(Android_图片的三级缓存一文)相关知识
https://android.googlesource.com/platform/frameworks/volley
(1).封装MyVolley类
在使用Volley之前,应该先进行初始化(可以自定义Application或者在SplashActivity中完成初始化),仅对外提供RequestQueue(添加request)和ImageLoader(下载图片)get方法!
/** * MyVolley.java * @see http://blog.csdn.net/zimo2013 * @author zimo2013 * */public class MyVolley {private static final String TAG = "MyVolley";private static MyVolley instance;private static RequestQueue mRequestQueue;private static ImageLoader mImageLoader;private final static int RATE = 8; // 默认分配最大空间的几分之一private MyVolley(Context context) {mRequestQueue = Volley.newRequestQueue(context);// 确定在LruCache中,分配缓存空间大小,默认程序分配最大空间的 1/8ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);int maxSize = manager.getMemoryClass() / RATE; // 比如 64M/8,单位为M// BitmapLruCache自定义缓存class,android本身支持二级缓存,在BitmapLruCache封装一个软引用缓存mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache(1024 * 1024 * maxSize));Log.i(TAG, "MyVolley初始化完成");}/** * 初始化Volley相关对象,在使用Volley前应该完成初始化 * * @param context */public static void init(Context context) {if (instance == null) {instance = new MyVolley(context);}}/** * 得到请求队列对象 * * @return */private static RequestQueue getRequestQueue() {throwIfNotInit();return mRequestQueue;}/** * 得到ImageLoader对象 * * @return */public static ImageLoader getImageLoader() {throwIfNotInit();return mImageLoader;}public static void addRequest(Request<?> request) {getRequestQueue().add(request);}public static void getImage(String requestUrl, ImageView imageView) {getImage(requestUrl, imageView, 0, 0);}public static void getImage(String requestUrl, ImageView imageView,int defaultImageResId, int errorImageResId) {getImage(requestUrl, imageView, defaultImageResId, errorImageResId, 0,0);}public static void getImage(String requestUrl, ImageView imageView,int defaultImageResId, int errorImageResId, int maxWidth,int maxHeight) {imageView.setTag(requestUrl);getImageLoader().get(requestUrl, ImageListenerFactory.getImageListener(imageView, defaultImageResId, errorImageResId), maxWidth,maxHeight);}/** * 检查是否完成初始化 */private static void throwIfNotInit() {if (instance == null) {// 尚未初始化throw new IllegalStateException("MyVolley尚未初始化,在使用前应该执行init()");}}}(2).图片的三级缓存相关类
/** * LruCache缓存管理类,该类实现了ImageCache接口,并实现了LruCache * 一旦bitmap对象从LruCache中被挤出,将会被放置在BitmapSoftRefCache中,再配合该框架本身支持的硬盘缓存,可以完成图片三级缓存 * * BitmapLruCache.java * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * */public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageCache {private static final String TAG = "BitmapLruCache";private BitmapSoftRefCache softRefCache;public BitmapLruCache(int maxSize) {super(maxSize);softRefCache = new BitmapSoftRefCache();}@Overrideprotected int sizeOf(String key, Bitmap value) {return value.getRowBytes() * value.getHeight();}@Overrideprotected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {if (evicted) {LogUtil.i(TAG, "空间已满,缓存图片被挤出:" + key);// 将被挤出的bitmap对象,添加至软引用BitmapSoftRefCachesoftRefCache.putBitmap(key, oldValue);}}/** * 得到缓存对象 */@Overridepublic Bitmap getBitmap(String url) {Bitmap bitmap = get(url);// 如果bitmap为null,尝试从软引用缓存中查找if (bitmap == null) {bitmap = softRefCache.getBitmap(url);} else {LogUtil.i(TAG, "LruCache命中:" + url);}return bitmap;}/** * 添加缓存对象 */@Overridepublic void putBitmap(String url, Bitmap bitmap) {put(url, bitmap);}}/** * 软引用缓存管理类 * * BitmapSoftRefCache.java * @author zimo2013 * @see http://blog.csdn.net/zimo2013 * */public class BitmapSoftRefCache implements ImageCache{private static final String TAG = "BitmapSoftRefCache";private LinkedHashMap<String, SoftReference<Bitmap>> map;public BitmapSoftRefCache() {map = new LinkedHashMap<String, SoftReference<Bitmap>>();}/** * 从软引用集合中得到Bitmap对象 */@Overridepublic Bitmap getBitmap(String url) {Bitmap bitmap = null;SoftReference<Bitmap> softRef = map.get(url);if(softRef != null){bitmap = softRef.get();if(bitmap == null){map.remove(url); //从map中移除LogUtil.w(TAG, url+"对象已经被GC回收");}else{LogUtil.i(TAG, "命中"+url);}}return bitmap;}/** * 从软引用集合中添加bitmap对象 */@Overridepublic void putBitmap(String url, Bitmap bitmap) {SoftReference<Bitmap> softRef = new SoftReference<Bitmap>(bitmap);map.put(url, softRef);}}
(3).图片错位
关于使用该框架造成图片错位问题,App使用了ImageLoader下载图片,当ListView滚动很快时,还是会发生错位!记得听别人提起过,使用该框架可以避免图片错位,但是结果还是会发生错位,查看源码并没有找到相关避免错位的措施,不知道是不是自己的使用方法不对,如您知晓,麻烦告知博主一下~
这里通过覆写ImageListener方法,通过ImageView为其指定Tag标签,防止图片错位,即比对下载完图片的ImageUrl和当前该ImageView的Tag是否相等~
public class ImageListenerFactory{public static ImageListener getImageListener(final ImageView view, final int defaultImageResId, final int errorImageResId) { return new ImageListener() { @Override public void onErrorResponse(VolleyError error) { if (errorImageResId != 0) { view.setImageResource(errorImageResId); } } @Override public void onResponse(ImageContainer response, boolean isImmediate) { if (response.getBitmap() != null) { if(view.getTag().toString() == response.getRequestUrl()){ view.setImageBitmap(response.getBitmap()); }else{ LogUtil.i(TAG, "图片错位"); } } else if (defaultImageResId != 0) { view.setImageResource(defaultImageResId); } } }; }}
2.网络请求Request
(1).StringRequest
public void testStringRequest(){String url = "http://www.baidu.com";//如果出现乱码,应该修改StringRequest的parseNetworkResponse()方法,指定byte[]-->String 编码MyVolley.getRequestQueue().add(new StringRequest(url, new Response.Listener<String>() {@Overridepublic void onResponse(String response) {System.out.println("response:"+response);}}, new Response.ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {}}));}(2).JsonObjectRequest
public void testJsonObjectRequest(){String url = "http://api.mobile.meituan.com/group/v1/deal/new-cate-list/android/4.1?cityId=1";//如果出现乱码,应该修改StringRequest的parseNetworkResponse()方法,指定byte[]-->String 编码MyVolley.getRequestQueue().add(new JsonObjectRequest(url,null, new Response.Listener<JSONObject>() {@Overridepublic void onResponse(JSONObject response) {//该JSONObject为android系统提供的,如果希望得到一个已经解析完的对象,可以继承JsonRequest//根据response,解析数据try {System.out.println(response.get("stid"));} catch (JSONException e) {e.printStackTrace();}}},new Response.ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {System.out.println(error);}}));}(3).自定义Request(Json解析)
/** * MyJsonRequest.java * * @author zimo2013 */public class MyJsonListRequest<T> extends JsonRequest<T> {private Gson gson;private Class<T> clazz;private String mKey;/** * GET请求方式,直接将json字符串解析为 对应的clazz对象 * * @param url * 请求url * @param clazz * 解析的class字节码 * @param listener * 请求成功监听器 * @param errorListener * 请求失败监听器 */public MyJsonListRequest(String url, Class<T> clazz, Listener<T> listener,ErrorListener errorListener) {this(url, null, clazz, listener, errorListener);}/** * GET请求方式,将json中的key对应的value解析为 对应的clazz对象 * * @param url * 请求url * @param key * 取得指定的key,<b>NOTE:</b>只支持 root-key,所有子key均错误 * @param clazz * 解析的class字节码 * @param listener * 请求成功监听器 * @param errorListener * 请求失败监听器 */public MyJsonListRequest(String url, String key, Class<T> clazz,Listener<T> listener, ErrorListener errorListener) {this(Method.GET, url, null, key, clazz, listener, errorListener);}/** * * @param method * 请求方法 Use {@link com.android.volley.Request.Method}. * @param url * @param requestBody * 如果是POST请求,可以提交form表单字符串,比如 name=zhangsan&age=20 * @param key * 取得指定的key,<b>NOTE:</b>只支持 root-key,所有子key均错误 * @param clazz * 解析的class字节码 * @param listener * 请求成功监听器 * @param errorListener * 请求失败监听器 */public MyJsonListRequest(int method, String url, String requestBody,String key, Class<T> clazz, Listener<T> listener,ErrorListener errorListener) {super(method, url, null, listener, errorListener);this.clazz = clazz;mKey = key;gson = new Gson();}@Overrideprotected Response<T> parseNetworkResponse(NetworkResponse response) {try {String json = new String(response.data,HttpHeaderParser.parseCharset(response.headers));T t = null;if(mKey == null){t = gson.fromJson(json, clazz);}else{JsonObject jsonObject = gson.fromJson(json, JsonObject.class);t = gson.fromJson(jsonObject.get(mKey), clazz);}return Response.success(t,HttpHeaderParser.parseCacheHeaders(response));} catch (UnsupportedEncodingException e) {return Response.error(new ParseError(e));} catch (JsonSyntaxException e) {return Response.error(new ParseError(e));}}}public void testCustomRequest(){String urlString = "http://192.168.117.120:8080/news/json.html";MyJsonRequest<NewsInfo> request = new MyJsonRequest<NewsInfo>(urlString, NewsInfo.class, new Listener<NewsInfo>() {@Overridepublic void onResponse(NewsInfo response) {System.out.println(response.getClass());System.out.println(response);}}, null);MyVolley.getRequestQueue().add(request);}(4).POST表单提交
public void testRequestByPost(){String urlString = "http://192.168.43.240:8080/news/servlet/Post";StringRequest request = new StringRequest(Method.POST, urlString, new Listener<String>() {@Overridepublic void onResponse(String response) {}}, new ErrorListener() {@Overridepublic void onErrorResponse(VolleyError error) {}}){//覆写getBody()方法提交表单数据@Overridepublic byte[] getBody() {return "name=zhangsan&age=15".getBytes();}};MyVolley.getRequestQueue().add(request);}(5).ImageLoader异步加载图片(防错位)
public void testImageLoader(){MyVolley.getImageLoader().get(imgUrl, //ImageListenerFactory为自定义类,封装后即可获取图片资源,完成UI更新ImageListenerFactory.getImageListener(//参考ImageLoader.getImageListener()imageView, // ImageView对象R.drawable.ic_launcher, // 默认Image,如果不设应置为0R.drawable.ic_launcher)); // 错误Image,如果不设应置为0}
- Android_开源框架_Volley实例
- Android_开源框架_Volley实例
- Android_开源框架_Volley实例
- Android_开源框架_Volley(Google IO 2013)源代码及内部实现分析
- Android_开源框架_Volley(Google IO 2013)源代码及内部实现分析
- Android_开源框架_Volley(Google IO 2013)源代码及内部实现分析
- Android_开源框架_Afinal
- Android_开源框架_JPush极光推送
- Android_开源框架_NineOldAndroids动画库
- Android_开源框架xUtils详解
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- Android_开源框架_AndroidUniversalImageLoader网络图片加载
- **Android_开源框架_AndroidUniversalImageLoader网络图片加载**
- PHP 上传文件大小限制
- APNS推送通知的流程
- 模板
- TomcatPlugin 配置项目热启动方式
- vim1
- Android_开源框架_Volley实例
- jquery dataTables demo
- 常用的sql语句
- 浅谈Overload和Override的区别
- HTTP请求报文和HTTP响应报文
- 解读ENVI Services Engine云解决方案
- Repeater的嵌套
- Android线程学习(三)之AsyncTask
- Android Intent 调用其他应用 setComponent