創(chuàng)建一個標準的 Request
這節(jié)課描述了如何使用 Volley 支持的普通類型的 request:
StringRequest
忘古,指定一個 URL 然后接收一個原始的 string临庇,看這里的例子 Setting Up a Request QueueImageRequest
钉鸯,指定一個 URL 然后接收一個圖片響應JsonObjectRequest
和JsonArrayRequest
(兩著都是JsonRequest
的子類)通贞,指定一個 URL 然后獲取一個 JSON 對象 或者 JSON 數(shù)組響應
如果你期望的響應是這些類型支子,你可能不需要實現(xiàn)一個自定義 request桶雀,這節(jié)課描述如何使用這些標準的 request 類型空执,更多如何實現(xiàn)一個自定義 request 的信息勋眯,查看 Implementing a Custom Request婴梧。
請求一張圖片
Volley 提供了一下類來實現(xiàn)圖片 request,這些不同層級的類支持不同等級的處理圖片:
ImageRequest
-一個可以通過給定 URL 獲取圖片并且回調(diào)返回一個 解碼后的 bitmap客蹋,同時也提供了便利方法比如指定一個尺寸大小來調(diào) 整接收到的圖片塞蹭。最主要的好處是 Volley 的線程計劃確保那些圖片操 作(解碼,調(diào)整大小)在 worker thread 中進行讶坯。ImageLoader
- 一個從遠程 URLs 加載和緩存圖片的助手類番电,ImageLoader
是個處理大量的ImageRequest
s 的協(xié)調(diào)類。例 如,當在 ListView 中填充多個縮略圖時漱办,ImageLoader
提 供一個在正常的 Volley cache 之前的 memory cache这刷,這樣能夠 有效防止閃爍。這使得實現(xiàn)一個 cache hit 不需要阻塞或者推遲 main thread娩井,這在使用磁盤 I/O 時所不能實現(xiàn)的暇屋。ImageLoader
也提供了響應合并特性,不需要每次使得 response 處理類來設(shè)置 bitmap 到一個 view 導致整個視圖數(shù)的從新布局洞辣,合并 response 使得能夠同時傳遞多個響應從而提高性能率碾。NetworkImageView
-建立在ImageLoader
上,在那種從網(wǎng)絡(luò)中加載圖片的情況下可以有效取代 ImageView屋彪,NetworkImageView
也可以自動管理取消 pending requests(待處理 request) 如果那個 view 已經(jīng)從視圖層級當中分離出去時所宰。
使用 ImageRequest
這里有一個使用 ImageRequest
的例子,它從指定 URL 中加載圖片任何顯示在 App 中畜挥,注意的代碼片段需要和一個通過單例類來獲取 RequestQueue
配合演示(查看 Setting Up a Request Queue 獲取描述此話題的詳情)
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
...
// Retrieves an image specified by the URL, displays it in the UI.
ImageRequest request = new ImageRequest(url,
new Response.Listener<Bitmap>() {
@Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(request);
使用 ImageLoader 和 NetworkImageView
你可以組合使用 ImageLoader
和 NetworkImageView
有效地管理顯示多張圖片仔粥,例如在 ListView 中,在你的布局 XML 文件中蟹但,你可以像使用 ImageView 一樣使用 NetworkImageView
躯泰,例如:
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/networkImageView"
android:layout_width="150dp"
android:layout_height="170dp"
android:layout_centerHorizontal="true" />
你可以單獨使用 ImageLoader
來加載顯示一張圖片,例如:
ImageLoader mImageLoader;
ImageView mImageView;
// The URL for the image that is being loaded.
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
...
mImageView = (ImageView) findViewById(R.id.regularImageView);
// Get the ImageLoader through your singleton class.
mImageLoader = MySingleton.getInstance(this).getImageLoader();
mImageLoader.get(IMAGE_URL, ImageLoader.getImageListener(mImageView,
R.drawable.def_image, R.drawable.err_image));
但是华糖,NetworkImageView
能夠幫你做這些工作如果你做的是填充一個 ImageView,例如:
ImageLoader mImageLoader;
NetworkImageView mNetworkImageView;
private static final String IMAGE_URL =
"http://developer.android.com/images/training/system-ui.png";
...
// Get the NetworkImageView that will display the image.
mNetworkImageView = (NetworkImageView) findViewById(R.id.networkImageView);
// Get the ImageLoader through your singleton class.
mImageLoader = MySingleton.getInstance(this).getImageLoader();
// Set the URL of the image that should be loaded into this view, and
// specify the ImageLoader that will be used to make the request.
mNetworkImageView.setImageUrl(IMAGE_URL, mImageLoader);
上面的代碼片段通過一個單例類來訪問 RequestQueue
和 ImageLoader
就像 Setting Up a Request Queue 描述的那樣,這種方式能夠確保你的 app 為這些類創(chuàng)建能夠持續(xù)整個 App 生命周期的單個實例麦向,這個對于 ImageLoader
(處理加載和緩存圖片的助手類)在 in-memory cache(內(nèi)存緩存) 這個主要的功能特性上能夠在非閃爍的情況下旋轉(zhuǎn)屏幕。使用單例模式能夠獨立于 activity 來緩存 bitmap客叉,如果你在一個 activity 上創(chuàng)建一個 ImageLoader
,當用戶每次旋轉(zhuǎn)屏幕時诵竭,ImageLoader
都會隨 activity 的重建而重建,這可能導致閃爍問題(沒有在 manifest XML 文件指定該 activity 的 configChanges 屬性)
LRU cache 例子:
Volley 工具盒提供 DiskBasedCache
類實現(xiàn)了一個標準的 cache,這個類緩存在指定的目錄下直接緩存文件兼搏,但是在使用 ImageLoader
時卵慰,你應該提供一個自定義的實現(xiàn) ImageLoader.ImageCache
接口實現(xiàn) in-memory LRU bitmap cache(LRU 內(nèi)存位圖緩存),你可能想要配置你的 cache 為一個單例佛呻,查看 Setting Up a Request Queue 了解更多信息
這里有一個實現(xiàn)內(nèi)存緩存的 LruBitmaoCache
類裳朋,它繼承 LruCache 類并實現(xiàn)了 ImageLoader.ImageCache
接口:
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.util.DisplayMetrics;
import com.android.volley.toolbox.ImageLoader.ImageCache;
public class LruBitmapCache extends LruCache<String, Bitmap>
implements ImageCache {
public LruBitmapCache(int maxSize) {
super(maxSize);
}
public LruBitmapCache(Context ctx) {
this(getCacheSize(ctx));
}
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
@Override
public Bitmap getBitmap(String url) {
return get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
put(url, bitmap);
}
// Returns a cache size equal to approximately three screens worth of images.
public static int getCacheSize(Context ctx) {
final DisplayMetrics displayMetrics = ctx.getResources().
getDisplayMetrics();
final int screenWidth = displayMetrics.widthPixels;
final int screenHeight = displayMetrics.heightPixels;
// 4 bytes per pixel
final int screenBytes = screenWidth * screenHeight * 4;
return screenBytes * 3;
}
}
這里有一個如何使用這個 cache 來實例化一個 ImageLoader
例子:
RequestQueue mRequestQueue; // assume this exists.
ImageLoader mImageLoader = new ImageLoader(mRequestQueue, new LruBitmapCache(
LruBitmapCache.getCacheSize()));
請求一個 JSON
Volley 提供下面這些類來實現(xiàn) JSON 請求
JsonArrayRequest
-一個根據(jù)指定 URL 請求和檢索一個 JSONArray 響應實體JsonObjectRequest
- 一個根據(jù)指定 URL 請求和檢索一個 JSONObject 響應實體,允許傳入一個可選的 JSONObject 作為請求實體
這兩個類都是基于普通的基類 JsonRequest
,你可以使用以下基本模式來使用其他類型的 request吓著,例如鲤嫡,下面的代碼片段獲取 JSON 并以文本形式顯示在 UI 上:
TextView mTxtDisplay;
ImageView mImageView;
mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
String url = "http://my-json-feed";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
mTxtDisplay.setText("Response: " + response.toString());
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
要實現(xiàn)一個自定義 JSON 請求基于 Gson,查看下節(jié)課程绑莺,Implementing a Custom Request.