Volley框架之一 如何使用

来源:互联网 发布:流量挂机赚钱软件 编辑:程序博客网 时间:2024/06/09 18:11

一直想找个优秀的开源框架学习下,Volley非常合适,研究下来学到了不少知识

Volley简介

Volley可是说是把AsyncHttpClient和Universal-Image-Loader的优点集于了一身,既可以像AsyncHttpClient一样非常简单地进行HTTP通信,也可以像Universal-Image-Loader一样轻松加载网络上的图片。除了简单易用之外,Volley在性能方面也进行了大幅度的调整,它的设计目标就是非常适合去进行数据量不大,但通信频繁的网络操作,而对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕。

先解释一下,对于大数据量的网络操作,比如说下载文件等,Volley的表现就会非常糟糕,为什么呢? 因为我们知道对于大文件的下载,我们一般的处理方式是把网络输入流直接写入文件,不写入内存,这样有效防止OOM,但是Volley,并没有针对大文件下载做任何处理,还是通用的实现,先写入内存,然后写入硬盘缓存。

导入Volley库

Google官方的Volley
android studio中添加volley
So Volley has been updated to Android studio build style which makes it harder create a jar. But the recommended way for eclipse was using it as a library project and this goes for android studio as well, but when workgin in android studio we call this a module. So here is a guide to how do it the way Google wants us to do it. Guide is based on this nice tutorial.

  1. First get latest volley with git (git clone https://android.googlesource.com/platform/frameworks/volley).
  2. In your current project (android studio) click [file] –[Import Module].
  3. Now select the directory where you downloaded Volley to.
  4. Now Android studio might guide you to do the rest but continue guide to verify that everything works correct
  5. Open settings.gradle (find in root) and add (or verify this is included):
    include ‘:app’, ‘:volley’
  6. Now go to your build.gradle in your project and add the dependency:
    compile project(“:volley”)

Thats all there is to it, much simpler and easier than compiling a jar and safer than relying on third parties jars or maven uploads.

另一个经常用的是 mcxiaoke/android-volley 这个非官方的volley项目优化了代码,据说解决了部分官方volley OOM的问题。后面会分析这个项目具体都解决了些什么问题。

  1. compile ‘com.mcxiaoke.volley:library:1.0.19-SNAPSHOT’
  2. 或者按照上面的方式,作为库项目添加到AS中

使用beyond compare
比较谷歌官方的volley和mcxiaoke/android-volley的区别
注意,因为两者格式不一样,所以不能通过文件的二进制格式比较,全选Compare Contents选择第三项,Rules-based compration按内容比较,那么就不会全线都飘红啦,可以很方便的知道那些文件修改过
最后发现其实没多大的区别,,,基本一样,所以使用哪个都可以

至于说会官方Volley会出现OOM那是很久以前的事了,现在不会。
CacheDispacher线程保持了context的引用,导致GC没有释放该Activity。可以看到现在最新的Volley的CacheDispacher并没有引用context,所以这个OOM是不会发生的

使用

这个就不多说了
想粗略的就参考这里吧 《Android Volley完全解析(一),初识Volley的基本用法》 一系列的文章

基本用法

注意以下地方

  1. mQueue只需要调用一次就行了Volley.newRequestQueue(this);这个方法内部会调用start方法,start方法默认开启1个缓存线程,4个网络请求线程。如果new多次了,那么系统资源肯定最后要被耗尽啊。
  2. mQueue如果能设置为单例的就最好不过了,就不用频繁的去创建销毁线程了,占用系统资源。Volley内部并没有使用线程池来管理缓存线程和网络请求线程。
  3. 如果mQueue没有设置为单例模式,那么onDestroy方法必须调用RequestQueue的stop方法,停止缓存线程和网络请求线程。这两个线程内部实现都是while无线循环的,除非调用了stop方法才退出while。想象一下,如果没有stop,那么启动一个activity,如果要做网络请求,那么就new一个RequestQueue,就是创建5个线程出来,但是没有去停止这几个线程,所以一直累积累积,最后后果不堪设想。
public class MainActivity extends AppCompatActivity {    private RequestQueue mQueue;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);        mQueue = Volley.newRequestQueue(this);    }    @OnClick(R.id.but)    void onClick() {        StringRequest stringRequest = new StringRequest("http://www.baidu.com",                new Response.Listener<String>() {                    @Override                    public void onResponse(String response) {                        QDLog.d("onResponse:" + response);                    }                }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                QDLog.d("onErrorResponse: " + error.getMessage());            }        });        mQueue.add(stringRequest);    }    @Override    protected void onDestroy() {        super.onDestroy();        mQueue.stop();    }}

post方法添加请求参数,重写StringRequest的getParams

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {    @Override    protected Map<String, String> getParams() throws AuthFailureError {        Map<String, String> map = new HashMap<String, String>();        map.put("params1", "value1");        map.put("params2", "value2");        return map;    }};

加载网络图片

提供了三种方式
1. ImageRequest
ImageRequest继承自Request,所以跟StringRequest等的使用方法差不多,提供了硬盘缓存,同时为了防止OOM对原图片进行了缩放处理。但是另一个问题,ImageRequest不适用于listview,gridview等滑动快速,需要频繁加载图片的场景,因为没有提供内存缓存。这个时候就需要使用ImageLoader咯,相比较ImageRequest,多了内存缓存的功能实现

2. ImageLoader
内部还是采用ImageRequest来实现的,只是添加了一级缓存(内存缓存)而已
下面的系列会介绍ImageRequest和ImageLoader的区别和联系

3. NetworkImageView
这个就不说了,NetworkImageView是一个自定义View,它是继承自ImageView的,具备ImageView控件的所有功能,并且在原生的基础之上加入了加载网络图片的功能

自定义Request

必须实现parseNetworkResponse(解析网络请求结果)和deliverResponse(分发结果)这两个方法

public class GsonRequest<T> extends Request<T> {    private final Listener<T> mListener;    private Gson mGson;    private Class<T> mClass;    public GsonRequest(int method, String url, Class<T> clazz, Listener<T> listener,            ErrorListener errorListener) {        super(method, url, errorListener);        mGson = new Gson();        mClass = clazz;        mListener = listener;    }    public GsonRequest(String url, Class<T> clazz, Listener<T> listener,            ErrorListener errorListener) {        this(Method.GET, url, clazz, listener, errorListener);    }    @Override    protected Response<T> parseNetworkResponse(NetworkResponse response) {        try {            String jsonString = new String(response.data,                    HttpHeaderParser.parseCharset(response.headers));            return Response.success(mGson.fromJson(jsonString, mClass),                    HttpHeaderParser.parseCacheHeaders(response));        } catch (UnsupportedEncodingException e) {            return Response.error(new ParseError(e));        }    }    @Override    protected void deliverResponse(T response) {        mListener.onResponse(response);    }}
0 0
原创粉丝点击