【Android开发】Volley学习笔记

来源:互联网 发布:sql中replace的用法 编辑:程序博客网 时间:2024/06/13 02:44

WiKi

Android2.2之前,最佳实践是采用HttpClient;Android 2.2版本之后,HttpURLConnection则是最佳的选择。在Android 5.0则全面废弃了HttpClient。
HttpURLConnection使用起来比较麻烦,Gooogle I/O 2013发布的一个处理和缓存网络请求的库即Volley。Volley的Socket通讯由HttpURLConnection负责,同时添加了多种上层封装。
Volley适合小而快的数据传输。Volley应该是简化了网络通信的一些开发,特别是针对以下两种情况:
• JSON对象
• 图片加载
Volley总共有3层架构。总得来说就是第1层是UI主线程,第2层是硬盘Cache层,第3层是PriorityBlockingQueue和线程池实现的“生产者-消费者”模型。最后将结果通知会UI主线程本质上是“Handler”机制。
这里写图片描述
解释该架构的文章比较多,更具体的内容可参见下一节的相关博客。

相关资料

Google官方Volley框架的4节Training
Android开源项目推荐之「网络请求哪家强」
volley源码解析(一)–volley的使用和架构
volley源码解析(二)–Request类的介绍
volley源码解析(四)–CacheDispatcher从缓存中获取数据
volley源码解析(五)–NetworkDispatcher从网络中获取数据
volley源码解析(六)–HurlStack与HttpClientStack之争
volley源码解析(七)–最终目的之Response

注意点

官方Training上有这么一段话
Volley is not suitable for large download or streaming operations, since Volley holds all responses in memory during parsing. For large download operations, consider using an alternative like DownloadManager.
即:在大量下载和流量操作方面Volley不适合,因为Volley在解析阶段在内存中保存了所有响应。对于大量的下载操作,应该使用DownloadManager。
另外一点注意,默认的Volley的响应结果都在UI主线程执行。当然可以重载来改变这一点。具体参考“volley 如何将返回结果放在非主线程?”。

Volley的典型应用

(1)StringRequest

RequestQueue queue=Volley.newRequestQueue(this);String url = "http://www.baidu.com";StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {    @Override    public void onResponse(String s) {        mTextView.setText("Response is: " + s.substring(0, 500));    }}, new Response.ErrorListener() {    @Override    public void onErrorResponse(VolleyError volleyError) {        mTextView.setText("That didn't work!");    }});stringRequest.setTag(TAG);

执行:

queue.add(stringRequest);

(2)ImageRequest
如果要求整个下载功能在应用的生命周期全过程,可以提供一个单例类。这里也把带有内存缓存功能的ImageLoader封装进去了。

/** * Created by CaoYF on 2016/8/16. */public class MySingleton {    private static MySingleton mInstance;    private RequestQueue mRequestQueue;    private ImageLoader mImageLoader;    private static Context mCtx;    private MySingleton(Context context) {        mCtx = context;        mRequestQueue = getRequestQueue();        mImageLoader = new ImageLoader(mRequestQueue,                new ImageLoader.ImageCache() {                    private final LruCache<String, Bitmap>                            cache = new LruCache<String, Bitmap>(20);                    @Override                    public Bitmap getBitmap(String url) {                        return cache.get(url);                    }                    @Override                    public void putBitmap(String url, Bitmap bitmap) {                        cache.put(url, bitmap);                    }                });    }    public static synchronized MySingleton getInstance(Context context) {        if (mInstance == null) {            mInstance = new MySingleton(context);        }        return mInstance;    }    public RequestQueue getRequestQueue() {        if (mRequestQueue == null) {            // getApplicationContext() is key, it keeps you from leaking the            // Activity or BroadcastReceiver if someone passes one in.            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());        }        return mRequestQueue;    }    public <T> void addToRequestQueue(Request<T> req) {        getRequestQueue().add(req);    }    public ImageLoader getImageLoader() {        return mImageLoader;    }}

然后用这个单例类来请求并加载图片。

String url2 = "http://i.imgur.com/7spzG.png";// Retrieves an image specified by the URL, displays it in the UI.ImageRequest imageRequest = new ImageRequest(url2,        new Response.Listener<Bitmap>() {            @Override            public void onResponse(Bitmap bitmap) {                mImageView.setImageBitmap(bitmap);            }        }, 0, 0, null,        new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError volleyError) {            }        });

执行

MySingleton.getInstance(MainActivity.this).addToRequestQueue(imageRequest);

(3)JSONObject
这里请求一个北京的天气预报,由于结果不是UTF-8,这里重写了JsonObjectRequest的parseNetworkResponse函数。

String url3 = "http://wthrcdn.etouch.cn/weather_mini?citykey=101010100";JsonObjectRequest jsObjRequest = new JsonObjectRequest        (Request.Method.GET, url3, null, new Response.Listener<JSONObject>() {            @Override            public void onResponse(JSONObject response) {                mTextView.setText("Response: " + response.toString());            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError error) {                // TODO Auto-generated method stub                mTextView.setText("Response: error");            }        }) {    @Override    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {        JSONObject jsonObject;        try {            jsonObject = new JSONObject(new String(response.data,"UTF-8"));            return Response.success(jsonObject, HttpHeaderParser.parseCacheHeaders(response));        } catch (JSONException e) {            e.printStackTrace();            return Response.error(new ParseError(e));        } catch (UnsupportedEncodingException e) {            e.printStackTrace();            return Response.error(new ParseError(e));        }    }};

执行

MySingleton.getInstance(MainActivity.this).addToRequestQueue(jsObjRequest);

(4)自定义请求类型
如果需要自定义请求类型,需要继承Request 并重写部分函数,具体参考Google官方Volley框架的4节Training最后一节的内容“Implementing a Custom Request”。

0 0
原创粉丝点击