Android之Volley框架在实际开发过程中运用
这个章节我们来讲下Volley在实际开发中如何正确地运用它。废话不说,进入正题。
集成 Volley
如果使用Android Studio开发的读者可以直接添加远程依赖:
compile 'com.mcxiaoke.volley:library:1.0.19'
如果使用Ecplise开发的读者可以在lib中加入jar,可以自己通过源码进行打包成jar,我这里就直接给出Volley.jar资源了。点此下载Volley.jar
Volley的Requst
final TextView mTextView = (TextView) findViewById(R.id.text);...// Instantiate the RequestQueue.RequestQueue queue = Volley.newRequestQueue(this);String url ="https://www.baidu.com/";StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(String response) { mTextView.setText("Response is: "+ response.substring(0,500)); }}, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { mTextView.setText("That didn't work!"); }});queue.add(stringRequest);
这是Volley的常规用法:
- 创建一个RequestQueue对象
- 创建一个继承自Request抽象类的子类请求对象
将请求对象加入到RequestQueue中
我们在StringRequest中传了四个参数,分别是:请求方法、url的字符串、请求成功的回调以及请求失败的回调。我们可以在回调中实现我们想要的具体逻辑。无论是StringRequest还是JsonRequest以及其他继承了Request类的对象,都是如此使用。
在开发过程中,比如在一个Activity有多个需要加载网络图片的ImageView,我们将多个Request加入到RequestQueue中,此时图片还没全部显示出来,我们点了后退键。此时,这个Acitivity销毁了,此时我们请求还在队列中,视图却已经销毁了,这样子就很容易造成效率的影响。所以我们可以在Activity中写如下代码:
public static final String TAG = MainActivity.class.getSimpleName();StringRequest stringRequest; // Assume this exists.RequestQueue mRequestQueue; // Assume this exists.// Set the tag on the request.stringRequest.setTag(TAG);// Add the request to the RequestQueue.mRequestQueue.add(stringRequest);
这里我们为每个Request设置了标签,并且标签最好以类名定义,这样子方便管理。然后我们在Activity的Stop方法中可以这么写:
@Overrideprotected void onStop () { super.onStop(); if (mRequestQueue != null) { mRequestQueue.cancelAll(TAG); }}
可以看到,我们取消掉了在RequestQueue中所有有此标签的Request。
Volley的RequestQueue:
在开发中,我们最好设计一个全局的RequestQueue对象,此时,你可能很容易想到在继承于Application中的Oncreate方法初始化它,但是这样子是不推荐的,会引起很多不必要的麻烦。现在我们通过单例模式来创建它:
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 cache = new LruCache(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) { mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext()); } return mRequestQueue; } public void addToRequestQueue(Request req) { getRequestQueue().add(req); } public ImageLoader getImageLoader() { return mImageLoader; }}
这里我们Volley.newRequestQueue(mCtx.getApplicationContext());
传入了了ApplicationContext对象,这是一个全局对象,如果我们传入了Activity或者Service的Context,就会引起内存泄漏。在这里初始化了RequestQueue对象以及一个ImageLoader。关于ImageLoader我们接下去再说,现在我们可以这样使用RequestQueue:
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()). getRequestQueue();MySingleton.getInstance(this).addToRequestQueue(stringRequest);
这样子就全局管理了RequestQueue。
Volley的NetworkImageView
Volley封装了一个继承自ImageView的NetworkImageView,还记得我们在RequestQueue单例中还初始化了一个ImageLoader吗,它能简单快捷地与NetworkImageView联合使用。我们可以在ListView的Item布局中使用NetworkImageView,然后用ImageLoader加载图片。
在Xml布局中定义很简单:
<com.android.volley.toolbox.NetworkImageView android:id="@+id/networkImageView" android:layout_width="150dp" android:layout_height="170dp" android:layout_centerHorizontal="true" />
然后在视图中代码可以这么写:
ImageLoader mImageLoader;NetworkImageView mNetworkImageView;private static final String IMAGE_URL = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);mImageLoader = MySingleton.getInstance(this).getImageLoader();mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
可以看到我们在这里mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
方法中只传入了一个url以及一个加载器就可以。
我们比较一下ImageView配合ImageLoader的代码:
ImageLoader mImageLoader;ImageView mImageView;private static final String IMAGE_URL = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png";mImageView = (ImageView) findViewById(R.id.regularImageView);mImageLoader = MySingleton.getInstance(this).getImageLoader();mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView, R.drawable.def_image, R.drawable.err_image));
很明显看到,代码不如用NetworkImageView与Imageloader配合来的简洁。
更多相关文章
- Android(安卓)Activity的启动过程过程分析
- android学习笔记之AIDL
- sqlite3加密方案sqlcipher,及sqlcipher使用指南
- Android简易音乐播放器之播放列表实现(第二篇)
- 快速开发android应用3-基于okhttp解析服务数据
- Android(安卓)fragment 传值
- android 使用开源库zxing生成二维码,扫描二维码
- Android启动流程简析(一)
- 如何成为一个偷懒又高效的Android开发人员