Volley Lesson 2 -Setting Up a RequestQueue(译)

原文:http://developer.android.com/training/volley/requestqueue.html

在上一篇文章Sending a Simple Request中展示了如何的简单的构造一个RequestQueue来充分利用Volley的默认的特性。这篇文章将展示如果通过一步一步来创建一个符合自己的需求的RequestQueue。

本片文章这描述了一种推荐的常用用法,创建一个单例的RequestQueue,使得其在我们的app的整个证明周期中都得到使用。

Set Up a Network and Cache

一个RequestQueue需要两部分来完成他的工作:一个网络network来传输其请求,一个cache来处理缓存。在Volley的toolbox中这些都有标准的实现:DiskBasedCache提供了一个cache,每一个response对应一个文件,并且在内存中拥有索引。BasicNetwork提供了标准的传输途径,可以选择androidHttpClient或者HttpURLConnection。

BasicNetwork是Volley的默认的network实现。一个BasicNetwork必须初始化一个Http客户端以便用来连接网络,典型的就是AndroidHttpClient或者HttpURLConnection。

  • AndroidHttpClient在API版本低于9(Gingerbread)的时候使用,在API低于9的版本中,HttpURLConnection是没有这个类的。更多的讨论可以参见 Android’s HTTP Clients.
  • HttpURLConnection可以用来API>=9的版本之中。

为了使得network能够在所有的Android平台上都能够使用,我们可以通过检测Android版本来调用不同的intent client。比如:

HttpStack stack;
...
// If the device is running a version >= Gingerbread...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
    // ...use HttpURLConnection for stack.
} else {
    // ...use AndroidHttpClient for stack.
}
Network network = new BasicNetwork(stack);

下面这个片段则展示了上面描述的内容在建立RequestQueu的时候,何时能够被调用:

RequestQueue mRequestQueue;

// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap

// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());

// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);

// Start the queue
mRequestQueue.start();

String url ="http://www.myurl.com";

// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
    @Override
    public void onResponse(String response) {
        // Do something with the response
    }
},
    new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            // Handle error
    }
});

// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
...

如果我们仅仅需要执行一次请求,那么我们可以在需要的时候建立RequestQueue,然后在stop()中取消掉queue。但更推荐的,更常用的一种办法是使用单例的设计模式来创建一个在整个app的生命周期中都能够使用的RequestQueue。

Use a Singleton Pattern

如果我们的程序一直需要使用网络的时候,那么更加有效,或者说效率更高的方式是通过单例模式来构建一个在整个app的生命中都能够访问到的RequestQueue。这有很多的途径,其中推荐的是使用单实例类,在该类中创建RequestQueue和其他的Volley需要的功能。另外一种实现的方式是可以继承Application类,然后再Application的onCreate()方法中创建RequestQueue,但这种方法并不推荐,因为单例模式可以以一种更加优雅的方法实现这个效果。

一个关键的概念就是,RequestQueue必须使用Application的context上下文来实例化,而不是Activity的context来实例化。这样可以保障ReqeueQueue可以在整个app的生命周期中都得到保持,而不会在每次activity重建的时候重新创建,比如设备旋转的时候。

这里有一个单例的类,提供了RequestQueue和ImageLoader的功能:

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;
    }
}

下面是使用的办法

/ Get a RequestQueue
RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
    getRequestQueue();
...

// Add a request (in this example, called stringRequest) to your RequestQueue.
MySingleton.getInstance(this).addToRequestQueue(stringRequest);

 

About: happyhls


发表评论

电子邮件地址不会被公开。 必填项已用*标注