Android 网络通信——Volley
来源:互联网 发布:成都 python兼职 编辑:程序博客网 时间:2024/06/03 09:23
Volley 是 Google 推出的 Android 异步网络请求框架和图片加载框架。在 Google I/O 2013 大会上发布。
Volley简介
Volley 的主要特点
1. 适合数据量小,通信频繁的网络操作
2. 扩展性强。Volley 中大多是基于接口的设计,可配置性强。
3. 一定程度符合 Http 规范,包括返回 ResponseCode(2xx、3xx、4xx、5xx)的处理,请求头的处理,缓存机制的支持等。并支持重试及优先级定义。
4. 默认 Android2.3 及以上基于 HttpURLConnection,2.3 以下基于 HttpClient 实现。
5. 提供简便的图片加载工具。
Volley实现的基本步骤:
首先创建一个请求队列,然后创建一个请求,将请求添加到请求队列中,Volley对队列中的请求进行处理。
Volley原理解析:
我们参照下图理解一下Volley处理网络请求的原理:
图中的概念:
Volley:
Volley 对外暴露的 API,通过 newRequestQueue(…) 函数新建并启动一个请求队列RequestQueue。
Request:
表示一个请求的抽象类。StringRequest、JsonRequest、ImageRequest都是它的子类,表示某种类型的请求。
RequestQueue:
表示请求队列,里面包含一个CacheDispatcher(用于处理走缓存请求的调度线程)、NetworkDispatcher数组(用于处理走网络请求的调度线程),一个ResponseDelivery(返回结果分发接口),通过 start() 函数启动时会启动CacheDispatcher和NetworkDispatchers。
CacheDispatcher:
一个线程,用于调度处理走缓存的请求。启动后会不断从缓存请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理。当结果未缓存过、缓存失效或缓存需要刷新的情况下,该请求都需要重新进入NetworkDispatcher去调度处理。
NetworkDispatcher:
一个线程,用于调度处理走网络的请求。启动后会不断从网络请求队列中取请求处理,队列为空则等待,请求处理结束则将结果传递给ResponseDelivery去执行后续处理,并判断结果是否要进行缓存。
ResponseDelivery:
返回结果分发接口,目前只有基于ExecutorDelivery的在入参 handler 对应线程内进行分发。
HttpStack:
处理 Http 请求,返回请求结果。目前 Volley 中有基于 HttpURLConnection 的HttpURLStack和 基于 Apache HttpClient 的HttpClientStack。
Network:
调用HttpStack处理请求,并将结果转换为可被ResponseDelivery处理的NetworkResponse。
Cache:
缓存请求结果,Volley 默认使用的是基于 sdcard 的DiskBasedCache。NetworkDispatcher得到请求结果后判断是否需要存储在 Cache,CacheDispatcher会从 Cache 中取缓存结果。
首先当有Request被添加到请求队列中请求网络时,Volley会先去Cache中查看是否有请求相同的URL地址的缓存,如果不久前请求过,则会调用CacheDispatcher线程处理获得缓存的返回结果;如果之前没有请求过,则会调用NetworkDispatcher线程处理请求,查看请求队列中有没有空闲的线程,如果有,则调用该线程访问URL,如果没有空闲的线程,则等待线程空闲下来。
Volley StringRequest使用
在前面我们已经讲了Volley基本使用,现在我们来看代码的实现:
1. 新建一个消息队列RequestQueue的对象,通过调用Volley.newRequestQueue(getApplicationContext())获得该对象。
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
2. 创建字符串请求消息队列的StringRequest 的请求。传入四个参数,第一个是请求的方法,第二个是请求的url,第三个参数是请求成功回调的方法,第四个是请求失败回调的方法。
GET方式请求:
StringRequest request = new StringRequest(Request.Method.GET, "http://192.168.0.44:8080/MyServiceTest/MyTestServlet", new Response.Listener<String>() { @Override public void onResponse(String response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } });
POST方式请求:
StringRequest request = new StringRequest(Request.Method.POST, "http://192.168.0.44:8080/MyServiceTest/MyTestServlet", new Response.Listener<String>() { @Override public void onResponse(String response) { } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { } }){ //重写了StringRequest中的getParams()方法。 @Override protected Map<String, String> getParams() throws AuthFailureError { HashMap<String, String > map = new HashMap<>(); map.put("username","zhangsan"); return map; } };
3. 请求队列调用add方法,将请求添加到请求队列中
queue.add(request);
Volley 单例使用
我们要知道,如果我们按照上面的方式实现,那么每次调用都会产生一个新的请求队列,这样每次发出请求都会添加到一个新的请求队列中。而我们想要的结果是每次的请求添加到同一个请求队列中,这样我们就需要使每次产生的请求队列是同一个,这就用到了“单例设计模式”。
实现代码如下:
public class MySingleton{ private String lock = "lock"; private static MySingleton mInstance; private RequestQueue mRequestQueue; private static Context mCtx; private MySingleton(Context context) { mCtx = context; mRequestQueue = getRequestQueue(); } public static MySingleton getInstance(Context context){ if(mInstance == null){ synchronized (lock){ if(mInstance == null){ mInstance = new MySingleton(context); } } } return mInstance; } public RequestQueue getRequestQueue(){ if(mRequestQueue == null){ mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); } return mRequestQueue; } //将请求添加到队列中 public void addToRequestQueue(Request req){ getRequestQueue().add(req); }}
Activity中我们通过按钮的点击事件连接网络,然后将返回数据显示在TextView中:
public class VolleyBaseActivity extends Activity implements OnClickListener { private Button mButtonVolleyGet; private TextView mTextViewContent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_volley_base); mButtonVolleyGet = (Button) findViewById(R.id.button_volleyget); mTextViewContent = (TextView) findViewById(R.id.textview_content); mButtonVolleyGet.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.button_volleyget: //创建请求 StringRequest request = new StringRequest(Request.Method.POST, "http://192.168.0.44:8080/MyServiceTest/MyTestServlet", new Response.Listener<String>() { @Override public void onResponse(String response) { mTextViewContent.setText(response);//将连接成功后,返回的信息输出到TextView中。 } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mTextViewContent.setText("网络连接错误");//如果连接失败,在TextView出显示信息"网络连接失败"。 } }) { @Override protected Map<String, String> getParams() throws AuthFailureError { HashMap<String, String> map = new HashMap<>(); map.put("username", "zhangsan"); return map; } }; //创建请求队列并将请求添加到请求队列中 MySingleton.getInstance(getApplicationContext()).addToRequestQueue(request); break; default: break; } }}
Volley ImageRequest使用
图片加载请求是使用ImageRequest的,但是ImageRequest的使用比较繁琐,Android中就将其进行了封装,使用ImageLoader。我们将ImageLoader也采用单例设计模式。
public class MySingleton{ private static MySingleton mInstance; private RequestQueue mRequestQueue;//消息队列 private ImageLoader mImageLoader;//ImageLoader对象 private static Context mCtx; private MySingleton(Context context) { mCtx = context; mRequestQueue = getRequestQueue(); mImageLoader = getImageLoader(); } public static synchronized MySingleton getInstance(Context context){ if(mInstance == null){ mInstance = new MySingleton(context); } return mInstance; } public RequestQueue getRequestQueue(){ if(mRequestQueue == null){ mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); } return mRequestQueue; } public ImageLoader getImageLoader(){ if(mImageLoader==null){ mImageLoader = new ImageLoader(getRequestQueue(), new ImageLoader.ImageCache(){ private final LruCache<String,Bitmap> cache = new LruCache<String,Bitmap>(20);//设置图片缓存 @Override public Bitmap getBitmap(String url) { return null; } @Override public void putBitmap(String url, Bitmap bitmap) { } }); } return mImageLoader; } //将请求添加到队列中 public void addToRequestQueue(Request req){ getRequestQueue().add(req); }}
Activity中我们通过点击按钮将图片显示出来。这里我们先显示网络图片使用NetworkImageView,因为NetworkImageView加载网络图片比较简单,只需要调用setImageUrl(URL url, ImageLoader loader)方法即可,方法传入两个参数,第一个是图片的URL地址,第二个是ImageLoader对象。
public class ImageRequestActivity extends Activity implements View.OnClickListener { private Button mButtonGetImage; private NetworkImageView mNetworkImageView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_request); mButtonGetImage = (Button) findViewById(R.id.button_get_image); mNetworkImageView = (NetworkImageView) findViewById(R.id.imageview); mButtonGetImage.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.button_get_image: //获得ImageLoader的对象。 ImageLoader loader = MySingleton.getInstance(getApplicationContext()).getImageLoader(); //调用setImageUrl方法 mNetworkImageView.setImageUrl("http://pic.nipic.com/2007-11-09/2007119122519868_2.jpg", loader); break; default: break; } }}
JsonRequest的使用与StringRequest的使用是相同的,只不过在后期对数据的处理不同。在此不在列举JsonRequest的使用。
- Android 网络通信——Volley
- Android网络通信请求框架——Volley
- Android网络通信必备神器Volley详解——初识Volley
- Android网络通信框架:Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- Android网络通信框架Volley
- android 网络通信库volley
- Android-网络通信HTTP-Volley
- Android 网络通信框架Volley
- android---(volley网络通信框架)
- Android Volley网络通信框架
- Android-Volley网络通信框架
- Android 网络通信框架Volley
- 【C++】写时拷贝COW
- SQL Server 2012 AlwaysOn高可用配置之八:新建可用性组
- 0913Android基础网络技术之Volley
- 0913Android基础网络技术之下载(AsyncTask)
- gradle--第九章 快速开始Groovy
- Android 网络通信——Volley
- linux设置默认从字符界面启动
- Hashtable&HashMap
- 我用闲言碎语,脱掉了你的外衣。
- 【读书笔记】iOS-对象初始化
- 基本常识
- 【特种兵PPT教程】如何用麦肯锡的金字塔原理做好PPT的“前戏”?
- C++Primer第五版 6.1节练习
- 2015年9月14日-学习笔记