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<String>() {
    @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的常规用法:

  1. 创建一个RequestQueue对象
  2. 创建一个继承自Request抽象类的子类请求对象
  3. 将请求对象加入到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方法中可以这么写:

@Override
protected 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<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) {
            mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
        return mRequestQueue;
    }

    public <T> void addToRequestQueue(Request<T> 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之Volley框架在实际开发过程中运用)