码迷,mamicode.com
首页 > 移动开发 > 详细

Android-Volley

时间:2015-12-07 00:27:59      阅读:329      评论:0      收藏:0      [点我收藏+]

标签:

1、volley简介

1volley其实是一个网络请求框架,相当于xutilHttpUtil+BitmapUtil

2Volley的特点:     

1.支持高效并发访问get/post     

2.Activity声明周期联动。     

3.支持网络图片和本地图片存储。     

4.支持访问排序:token

2、Volley中两个核心类

2.1Request:请求

1StringRequest:返回字符串

2JsonObjectRequest:返回json对象

解析json两种方式

response.getString("name");//方式一:当key不存在会出现异常,不建议使用

response.optString("name");//方式二:key不存在,返回默认值,""

3JsonArrayRequestjson数组

4ImageRequest:返回bitmap对象。 

ImageRequest构造函数几个重要参数: 

new ImageRequest(arrayUrl, listener, maxWidth, maxHeight, decodeConfig, errorListener); 

①maxWidth、maxHeight: //0显示原始图片大小,指定大小则会对图片压缩处理

②decodeConfig: 

Config.ALPHA_8->8->一个字节     

ARGB_444416   2个字节       

ARGB_8888      32   4个字节          

RGB_565       16   2个字节 

图片格式选择:     

Volley使用RGB_565     

xutil:RGB_565     

UIL:ARGB_8888 

2.2RequestQueue:请求队列

3、Volley开发三部曲

①创建对应的Request对象

②创建RequestQueue请求队列

③将request对象添加到请求队列中

示例:

1)StringRequest

// 创建对应的Request对象
        StringRequest request = new StringRequest(url, new Listener<String>() {

            @Override
            public void onResponse(String response) {
                System.out.println(response);
            }
        }, new ErrorListener() {
    
            @Override
            public void onErrorResponse(VolleyError error) {
                System.out.println(error.getMessage());
            }
        });
        // 创建RequestQueue请求队列
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        // 添加到请求队列中
        requestQueue.add(request);
    }

2) JsonObjectRequest

    //1创建JsonObjectRequest对象
    JsonObjectRequest request = new JsonObjectRequest(url, null,
            new Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {
                    // 解析json数据
                    // response.get("name");//当key不存在时,会抛出异常,不建议使用
                    String name = response.optString("name");// 当key不存在时,返回默认值“”。
                    int age = response.optInt("age");
                    String school = response.optString("school");
                    System.out.println("name=" + name + ",age=" + age+ ",school=" + school);
                    }
                }, new ErrorListener() {

                @Override
                public void onErrorResponse(VolleyError error) {
                    System.out.println(error.getMessage());
                }
            });
    //2.创建requestqueue对象
    RequestQueue requestQueue = Volley.newRequestQueue(context);
    //3.添加到请求队列中
    requestQueue.add(request);

3)jsonArrayRequest

private void jsonArrayRequest() {
        JsonArrayRequest request = new JsonArrayRequest(arrayUrl,
                new Listener<JSONArray>() {
                    /*
                     * "name": "Steve Jobs", "age": 69, "school": "CMU",
                     * "company": "Apple"
                     */
                    @Override
                    public void onResponse(JSONArray response) {
                        for (int i = 0; i < response.length(); i++) {
                            JSONObject jsonObject = response.optJSONObject(i);
                            String name = jsonObject.optString("name");
                            int age = jsonObject.optInt("age");
                            String school = jsonObject.optString("school");
                            String company = jsonObject.optString("company");
                            System.out.println("name=" + name + ",age=" + age
                                    + ",school=" + school + ",compamy="
                                    + company);
                        }
                    }
                }, new ErrorListener() {

                    @Override
                    public void onErrorResponse(VolleyError error) {
                    }
                });
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        requestQueue.add(request);

4)ImageRequest

 

private void imageRequest() {
        int maxWidth = 0;
        int maxHeight = 0;
        Config decodeConfig = Config.ALPHA_8;//8位表示一个字节
        //1创建ImageRequest对象
        ImageRequest request = new ImageRequest(imageUrl, new Listener<Bitmap>() {

            @Override
            public void onResponse(Bitmap response) {
                // 请求成功返回bitmap对象
                iv.setImageBitmap(response);                
            }
        }, maxWidth, maxHeight, decodeConfig, new ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                // TODO Auto-generated method stub
                
            }
        });
        //2.创建RequestQueue对象
        RequestQueue queue = Volley.newRequestQueue(context);
        //3.添加request到队列中
        queue.add(request);        
    }

4、图片压缩核心内容

原理:BitmapFactory.Options

decodeOptions.inJustDecodeBounds = true;// 获得图片宽度和高度,图片不加载到内存中,图片很大也不会OOM

decodeOptions.inSampleSize:采样率,值为2的几次方,8表示按 1/8缩小

4.1volley中的inSampleSize计算方式:

 static int findBestSampleSize(
  int actualWidth, int actualHeight, int desiredWidth, int desiredHeight)    
   {
        double wr = (double) actualWidth / desiredWidth;
        double hr = (double) actualHeight / desiredHeight;
        double ratio = Math.min(wr, hr);
        float n = 1.0f;
        while ((n * 2) <= ratio) {
            n *= 2;
        }
        return (int) n;
    }

4.2xutilinSample的算法: 

 final int height = options.outHeight;
 final int width = options.outWidth;
 int inSampleSize = 1;

  if (width > maxWidth || height > maxHeight) {
        if (width > height) {
            inSampleSize = Math.round((float) height / (float) maxHeight);
        } else {
          inSampleSize = Math.round((float) width / (float) maxWidth);
        }

        final float totalPixels = width * height;
         final float maxTotalPixels = maxWidth * maxHeight * 2;
         while (totalPixels/ (inSampleSize * inSampleSize) > maxTotalPixels)
         {
                inSampleSize++;
         }
  }
  return  ;

4.3UIL(图片缓冲)inSample的算法:

    final int srcWidth = srcSize.getWidth();
        final int srcHeight = srcSize.getHeight();
        final int targetWidth = targetSize.getWidth();
        final int targetHeight = targetSize.getHeight();

        int scale = 1;

        switch (viewScaleType) {
            case FIT_INSIDE:
                if (powerOf2Scale) {
                    final int halfWidth = srcWidth / 2;
                    final int halfHeight = srcHeight / 2;
                    while ((halfWidth / scale) > targetWidth || (halfHeight / scale) > targetHeight) { // ||
                        scale *= 2;
                    }
                } else {
                    scale = Math.max(srcWidth / targetWidth, srcHeight / targetHeight); // max
                }
                break;
            case CROP:
                if (powerOf2Scale) {
                    final int halfWidth = srcWidth / 2;
                    final int halfHeight = srcHeight / 2;
                    while ((halfWidth / scale) > targetWidth && (halfHeight / scale) > targetHeight) { // &&
                        scale *= 2;
                    }
                } else {
                    scale = Math.min(srcWidth / targetWidth, srcHeight / targetHeight); // min
                }
                break;
        }

        if (scale < 1) {
            scale = 1;
        }
        scale = considerMaxTextureSize(srcWidth, srcHeight, scale, powerOf2Scale);

        return scale;

5、VolleyNetWorkImageView的使用

NetWorkImageView:显示网络图片的控件

核心APIsetImageUrl(url , imageLoader);

5.1ImageCache对象

图片内存缓冲核心: public Bitmap getBitmap(String url) 

Public void putBitmap(String url, Bitmap bitMap)

5.2、四种引用级别 

1)强引用:平时使用的集合,比如ArrayListHashMapHashSet

  特点:oom也不回收内存

2)软引用:SoftReferenceHashMap<String, SoftReference<Bitmap>>

特点:内存不足,回收对象

以前开发使用软引用缓冲图片:2.3之后,谷歌建议建议使用LruCache代替。

(3)虚引用:形同虚设

4)弱引用:不使用

5.3LruCache介绍

(1LRUleast recently used,最近最少使用

(2)使用LinkedHashMap作为存储结构

new LinkedHashMap<K, V>(0, 0.75f, true)

第一个参数:初始化容器大小

第二个参数:负载因子,比如初始化容器大小16,负载因子0.7516 * 0.75=12 当容器有12个元素时,自动增长。

第三个参数:true代表按照最近访问顺序排序(LruCache选择LinkedHashMap的核心原因),false按照插入顺序排序

5.4、对LruCache的总结

缓存图片都要用到lrucache,它会用到lru算法,表示最近最少使用(可以扯一扯操作系统的页面置换算法及其原理),谷歌从安卓2.3后不建议使用软引用,是因为软引用当内存不足时会回收内存,我们应该在内存不足的之前,能处理应用不让它占用过多的内存。

查看源码发现LruCache内部用的数据结构是LinkedHashMap。使用map集合的原因是因为要存储图片是url-bitmmap键值对形式储存。选择map集合中的LinkedHashMap是因为其构造函数第三个参数决定,因为第三个参数使用lru

5.5NetWorkImageView使用案例:

public class MainActivity extends Activity {

    private NetworkImageView netWorkImg;
    private NetworkImageView netWorkImg2;
    private String url;
    private MainActivity context;
    private ImageLoader imageLoader;

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

        netWorkImg = (NetworkImageView) findViewById(R.id.netWorkImg);
        netWorkImg2 = (NetworkImageView) findViewById(R.id.netWorkImg2);
        url = "http://192.168.0.112:8080/imgs/movie4.PNG";
        context = this;
    }

    /**从网络获取图片*/
    public void loadImgFromNet(View v) {

        RequestQueue queue = Volley.newRequestQueue(context);
        ImageCache imageCache = new MyImageCache();
        imageLoader = new ImageLoader(queue, imageCache);
        
        netWorkImg.setImageUrl(url, imageLoader);
    }
    /**从网络内存缓冲图片*/
    public void loadImgFromRamCache(View v) {
        netWorkImg2.setImageUrl(url, imageLoader);
    }

    public class MyImageCache implements ImageCache {

        private LruCache bitmapCache;

        @SuppressLint("NewApi") 
        public MyImageCache() {
            int cacheSize = 4 * 1024 * 1024; // 缓冲图片最大占用空间
            bitmapCache = new LruCache(cacheSize) {
                @SuppressLint("NewApi")
                protected int sizeOf(String key, Bitmap value) {
                    return value.getByteCount()/1024/1024;//返回每张图片占用内存大小
                }
            };
        }
        //从缓冲中获取Bimap对象
        @SuppressLint("NewApi") @Override
        public Bitmap getBitmap(String url) {
            return (Bitmap) bitmapCache.get(url);
        }
        @SuppressLint("NewApi") @SuppressWarnings("unchecked")
        @Override
        //从图片缓冲的内存
        public void putBitmap(String url, Bitmap bitMap) {
            bitmapCache.put(url, bitMap);
        }
    }
}

activity销毁时,也应该取消网络访问,可在activity中的finish()方法中,取消网络访问。

HttpClient停止网络请求:

HttpClient.getConnectiontManager()

ClientConnectionManager.shutdown()停止访问网络

 Volley取消网络

1RequestQueue.stop(),取消单个网络访问

2RequestQueue.cancleAll(tag)取消所有网络,

7Volley中的ImageLoader(现在开发中都是用UIL

可以用来显示网络图片

RequestQueue queue = Volley.newRequestQueue(this);
ImageLoader imageLoader = new ImageLoader(queue , new MyImageCache());
String url = "http://192.168.199.238:8080/imgs/car5.PNG";
imageLoader.get(url, new ImageListener() {
            
    @Override
    public void onErrorResponse(VolleyError error) {
        Toast.makeText(MainActivity.this,error.getMessage(), 0).show();
    }
            
    @Override
    public void onResponse(ImageContainer response, boolean isImmediate) {
        Bitmap bitmap = response.getBitmap();
        mImageView.setImageBitmap(bitmap);
    }
});    

 

Android-Volley

标签:

原文地址:http://www.cnblogs.com/znouy/p/5024689.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!