Volley的初步了解
Volley的介绍
- Volley是什么?
- 2013年Google I/O大会上推出的网络请求和图片加载框架
- 其优点是api简单,性能优秀
- 非常适合数据量不大但是通信频繁的网络请求,而对于大数据量的操作,如文本下载,表现则没有那么好
- Volley内部仍然是使用的HttpURLConnection和HttpClient进行网络请求的,只是对于不同的Android版本进行了响应的切换,2.3之前使用的HttpClient,2.3之后使用的是HttpURLConnection 这是因为在2.3版本之前,HttpURLConnection有一个很严重的bug,当开启请求的时候会造成线程池无法关闭。
- 为什么用Volley,相比XUtil,Volley解决了以下问题:
- 当用户finish当前的Activity的时候,而当前Activity正在进行网络请求,Volley支持取消网络请求
- 当用户旋转屏幕,Activity重新创建,那么同样的网络请求会从新发送,而Volley支持对重复的请求进行缓存
- 支持多样的网络请求返回封装
3. Volley的使用
首先,引入Volley类库,添加相关权限
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>Volley中的核心类
- Request,请求类,有几个实现类
- StringRequest:请求的时候直接回来一个String
- JsonObjectRequest:请求的时候直接回来一个JsonObject
- JsonArrayRequest:请求的时候直接回来一个JsonArray
- ImageRequest:请求的时候直接回来一个Bitmap
- 自定义请求:一会我们会结合gson
- RequestQueue:请求队列,用来执行Request的
- ImageLoader:图片加载的类
- NetWorkImageView:继承自ImageView,可以直接加载网络图片
- Request,请求类,有几个实现类
创建请求队列RequestQueue
RequestQueue queue = Volley.newRequestQueue(this);
使用StringRequest进行请求
//2.创建网络请求
StringRequest stringRequest = new StringRequest(url, new Listener<String>() {
@Override
public void onResponse(String response) {
tv_result.setText(response);
}
},new MyErrorListener());
//3.执行请求
queue.add(stringRequest);使用JsonRequest进行请求
//1.创建JsonRequest请求
JsonObjectRequest joRequest = new JsonObjectRequest(url, null, new Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
tv_result.setText(response.toString());
}
}, new MyErrorListener());
//2.执行请求
queue.add(joRequest);使用JsonArrayRequest进行请求
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(listUrl, new Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
tv_result.setText(response.toString());
}
}, new MyErrorListener());
queue.add(jsonArrayRequest);使用ImageRequest进行请求
ImageRequest imageRequest = new ImageRequest(imageUrl,new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
iv_result.setImageBitmap(response);
}
}, 200, 100, Config.RGB_565, new MyErrorListener());
queue.add(imageRequest);
4. 加载图片的压缩处理的核心
第一步: 从原图进行等宽高比的采样,采样的值最好是2的倍数,代码如下:
Options opts = new Options();
opts.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts);第二步: 根据图片的原始宽高比和控件的宽高比,科学的计算采样比例,代码如下:
Options opts = new Options();
opts.inJustDecodeBounds = true;//设置只解析图片的边界参数,即宽高
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts);
//科学计算图片所需的采样比例
opts.inSampleSize = caculateSampleSize(opts.outWidth,opts.outHeight); opts.inJustDecodeBounds = false;//关闭标记,解析真实的图片
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.fast, opts); /**
* 根据图片的原始宽高比和ImageView的宽高计算图片的采样比例
* @param outWidth
* @param outHeight
* @return
*/
private int caculateSampleSize(int outWidth, int outHeight) {
int inSampleSize = 1;
if(outWidth>outHeight){
//参考宽进行缩放
inSampleSize = outWidth/iv_result.getWidth();//1920/300
}else{
//参考高进行缩放
inSampleSize = outHeight/iv_result.getHeight();
}
if(inSampleSize<1){
inSampleSize = 1;
}
return inSampleSize;
}第三步: 设置图片加载的渲染模式为Config.RGB_565,能降低一半内存:
opts.inPreferredConfig = Config.RGB_565
5. Volley中的ImageLoader使用以及内存缓存详解
使用ImageLoader加载图片
protected void loadImage() {
ImageListener imageListener = ImageLoader.getImageListener(iv_result, R.drawable.ic_launcher, R.drawable.ic_launcher);
MemoryCache imageCache = new MemoryCache();
ImageLoader imageLoader = new ImageLoader(queue, imageCache);
imageLoader.get(imageUrl, imageListener);
}
/**
* 图片内存缓存
* @author lxj
*
*/
public class MemoryCache implements ImageCache{
private LruCache<String, Bitmap> lruCache;
//app可用内存的8分之一
private int maxSize = (int) (Runtime.getRuntime().totalMemory()/8);
public MemoryCache(){
lruCache = new LruCache<String, Bitmap>(maxSize){
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getHeight()*value.getRowBytes();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return lruCache.get(url);
} @Override
public void putBitmap(String url, Bitmap bitmap) {
lruCache.put(url, bitmap);
}
}内存缓存详解
- 内存缓存的存储结构:一般是map,因为需要存取
在Android2.3之前还没有好的内存缓存策略出现,一般采用SoftRefrence对Bitmap进行包装,能尽量保证不会出现oom,几种引用的解释如下:
- 强引用 : 引用默认就是强引用, 即使内存oom, 也不会去回收对象
软应用:使用SoftRefrence去包装一个对象,内存不足的时候去回收对象,尽量保证不oom,代码如下:
HashMap<String, SoftReference<Bitmap>> map = new HashMap<String, SoftReference<Bitmap>>();
SoftReference<Bitmap> reference = map.get(url);
Bitmap bitmap = reference.get();- 弱引用:使用WeakReference保证一个对象,一般不用
- 在Android2.3之后Google提供了Lru算法的实现类,即LruCache,并推荐我们使用LruCache来实现图片的内存缓存,该类有效解决了Android中图片内存缓存的难题,常见几种内存缓存策略有:
- Least Frequently Used(LFU): 删除使用频率最少的
- Least Recently Used(LRU): 删除最近最少使用的
- First in First out(FIFO): 删除最先添加进来的
- Most Recently Used(MRU): 删除最近最多使用的
- LruCache内部实现原理(重点):
- 内部使用按照访问顺序排序的LinkedHashMap来存储数据
- 每次缓存命中,该条会按照元素的访问次数进行重新排序
- 并会判断缓存size是否超出maxSize,如果超出则移除最下方的数据,即最少使用的数据
- 我们必须实现sizeOf方法,用来指定每条数据的size,此处是返回bitmap的大小
- 了解XUtil等开源类库对图片内存缓存的实现
- 了解图片的磁盘缓存的实现DiskLruCache
6. Volley中的NetworlImageView的使用
MemoryCache imageCache = new MemoryCache();
ImageLoader imageLoader = new ImageLoader(queue, imageCache);
net_imageview.setImageUrl(imageUrl, imageLoader);
7. 自定义Volley的Request
- 我们在开发中更多的是请求一个url,然后将结果解析为java bean,所以封装一个具有该功能的Request类,GosnRequest
代码如下:
protected void execGsonRequest() {
GsonRequest<Stu> gsonRequest = new GsonRequest<Stu>(url, Stu.class, new Listener<Stu>() {
@Override
public void onResponse(Stu stu) {
tv_result.setText(stu.toString());
}
}, new MyErrorListener());
queue.add(gsonRequest);
}
public class GsonRequest<T> extends Request<T>{
private Class<T> clazz;
private final Listener<T> mListener;
public GsonRequest(String url,Class<T> clazz,Listener<T> listener, ErrorListener errorListener) {
super(url, errorListener);
mListener = listener;
this.clazz = clazz;
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
//解析json,返回response
T t = new Gson().fromJson(parsed,clazz );
return Response.success(t, HttpHeaderParser.parseCacheHeaders(response));
}
@Override
protected void deliverResponse(T response) {
mListener.onResponse(response);
}
}
8. 使用Volley取消网络请求
给每个Request添加tag标识
stringRequest.setTag(this);
调用取消请求的方法
queue.cancelAll(this);
9. 使用Volley发送post请求,需要自己重写Request的getParams方法
public class PostReuqest extends StringRequest {
private Map<String, String> params;
public PostReuqest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
super(url, listener, errorListener);
}
public PostReuqest(int method,String url, Response.Listener<String> listener, Response.ErrorListener errorListener) {
super(method,url, listener, errorListener);
}
public void setParams(Map<String, String> params){
this.params = params;
}
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return params;
}
}
PostReuqest stringRequest = new PostReuqest(Request.Method.POST,Api.LOGIN, new com.android.volley.Response.Listener<String>() {
@Override
public void onResponse(String response) {
text.setText(response);
}
}, new com.android.volley.Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
HashMap<String,String> map = new HashMap<>();
map.put("username","hehehe");
map.put("password","12321");
stringRequest.setParams(map);
10. 对Volley进行二次封装
/**
* Volley的二次封装类
* @author lxj
*
*/
public class VolleyHelper {
private RequestQueue requestQueue;
MemoryCache imageCache = new MemoryCache();
private static VolleyHelper mInstance = null;
private VolleyHelper(Context context){
requestQueue = Volley.newRequestQueue(context); }
public static VolleyHelper get(Context context){
if(mInstance==null){
mInstance = new VolleyHelper(context);
}
return mInstance;
}
public <T> void executeRequest(Request<T> request){
requestQueue.add(request);
}
/**
* 执行GsonRequest
* @param url
* @param clazz
* @param listener
* @param errorListener
*/
public <T> void executeGsonRequest(String url,Class<T> clazz,Listener<T> listener,ErrorListener errorListener){
GsonRequest<T> gsonRequest = new GsonRequest<T>(url, clazz, listener, errorListener);
gsonRequest.setTag(url);
requestQueue.add(gsonRequest);
}
/**
* 取消请求
* @param tag
*/
public void cancelRequest(String tag){
requestQueue.cancelAll(tag);
}
/**
* 加载图片
* @param imageUrl
* @param imageView
*/
public void loadImage(String imageUrl,ImageView imageView){
ImageListener imageListener = ImageLoader.getImageListener(imageView, R.drawable.ic_launcher, R.drawable.ic_launcher);
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
imageLoader.get(imageUrl, imageListener);
}
}
Volley的初步了解的更多相关文章
- Android网络编程系列之Volley总结
前言 Volley的中文翻译为“齐射.并发”,是在2013年的Google大会上发布的一款Android平台网络通信库,具有网络请求的处理.小图片的异步加载和缓存等功能,能够帮助 Android AP ...
- 小记:对Android网络下载工具的初步封装!(包括json,字符串下载(volley),和图片下载(glide))
import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkIn ...
- Android 学习笔记之Volley开源框架解析(二)
PS:Volley已经学完,可以安心的写一下博客总结一下了... 学习内容: 1.Request的完整封装... 2.RetryPolicy,DefaultRetryPolicy(请求重试策略源码解析 ...
- Android网络通信Volley框架源代码浅析(三)
尊重原创 http://write.blog.csdn.net/postedit/26002961 通过前面浅析(一)和浅析(二)的分析.相信大家对于Volley有了初步的认识,可是假设想更深入的理解 ...
- 开源框架Volley的使用《二》[NetWorkImageView&&LruCache&ImageLoader]
转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:小杨的博客 http://blog.csdn.net/qq_32059827/article/details/5278849 ...
- 一口一口吃掉Volley(二)
欢迎访问我的个人博客转发请注明出处:http://www.wensibo.top/2017/02/17/一口一口吃掉Volley(二)/ 相信看了第一篇教程之后,你应该会对Volley有一个初步的了解 ...
- 移动端之Android开发的几种方式的初步体验
目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...
- CSharpGL(29)初步封装Texture和Framebuffer
+BIT祝威+悄悄在此留下版了个权的信息说: CSharpGL(29)初步封装Texture和Framebuffer +BIT祝威+悄悄在此留下版了个权的信息说: Texture和Framebuffe ...
- 快速Android开发系列网络篇之Volley
Volley是Google推出的一个网络请求库,已经被放到了Android源码中,地址在这里,先看使用方法 RequestQueue mRequestQueue = Volley.newRequest ...
随机推荐
- 系统重装 Ghost系统的disk to image等等是什么意思
localdiskto disk to imade from imagepartitionto partition to image from imagecheckimage file disk这些是 ...
- 剑指Offer面试题43(Java版):n个骰子的点数
题目:把n个骰子仍在地上.全部骰子朝上一面的点数之和为s,输入n,打印出s的全部可能的值出现的概率. 解法一:基于递归求骰子的点数,时间效率不够高 如今我们考虑怎样统计每个点数出现的次数. 要向求出n ...
- cf246 ENew Reform (并查集找环)
Berland has n cities connected by m bidirectional roads. No road connects a city to itself, and each ...
- 猫猫学iOS 之第一次打开Xcode_git配置,git简单学习
猫猫分享,必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:错误 当第一次打开Xcode我们进行commit操作的时候会 ...
- SQLServer导出单表数据
采用生成脚本---仅数据.. 如果是部分数据,可以先把部分数据备份到一个表中 select * into .. from ...
- 2016/05/16 UEditor 文本编辑器 使用教程与使用方法
第一:百度UEditor编辑器的官方下载地址 ueditor 官方地址:http://ueditor.baidu.com/website/index.html 开发文档地址:http://uedito ...
- select标签multiple属性的用法
前些日子公司让做一个功能模块.对于里面一个小功能费了些周折,现将其总结一下: 一.实现效果: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ2FvaHVh ...
- UVA - 11488 Hyper Prefix Sets(trie树)
1.给n个只含0.1的串,求出这些串中前缀的最大和. 例1: 0000 0001 10101 010 结果:6(第1.2串共有000,3+3=6) 例2: 01010010101010101010 1 ...
- anaconda tensorflow tflearn 自动安装脚本 anaconda使用-b可以非交互式安装
install_dir=/usr/local/anaconda3 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )&qu ...
- 并不对劲的bzoj5341:loj2553:uoj400:p4565:[Ctsc2018]暴力写挂
题目大意 有两棵\(n\)(\(n\leq366666\))个节点的树,\(T\)和\(T'\),有边权 \(dep(i)\)表示在\(T\)中\(i\)号点到\(1\)号点的距离,\(dep'(i) ...