一、volley是什麼?
1、簡介
Volley是Goole在2013年Google I/O大會上推出了一個新的網絡通信框架,它是開源的。從名字由來和配圖中無數急促的火箭可以看出 Volley 的特點:特別適合數據量小,通信頻繁的網絡操作。(個人認爲 Android 應用中絕大多數的網絡操作都屬於這種類型)。
Volley加載圖片實現了兩級緩存(網絡緩存、文件緩存),沒有實現內存的緩存。Volley已經把各種異步任務、圖片採樣都封裝好了。內存緩存使用lrucache類實現,需要我們手動添加進去。沒有使用軟引用緩存。因爲4.0之後的android系統已經不推薦使用軟引用緩存了。
2、volley的總體設計
3、volley可以做什麼
JSON,圖像等的異步下載;
處理get、post等網絡請求;
網絡請求的排序(scheduling);
網絡請求的優先級處理;
緩存;
多級別取消請求;
和Activity和生命週期的聯動(Activity結束時同時取消所有網絡請求);
等等。
二、圖片的三級緩存在volley中的實現
其實volley可以完全取代我們手寫的三級緩存,因爲google已經對volley進行了非常好的封裝,具體說明如下:
1、volley的推薦用法-單例模式
使用volley時,我們推薦把volley的使用封裝成單例使用。在application中初始化它。具體代碼如下:
單例:
package com.ht.xiangqu.util;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
/**
* Created by annuo on 2015/6/16.
*/
public class RequestManager {
private static RequestManager ourInstance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
public static RequestManager createInstance(Context context) {
if (context != null) {
if (ourInstance == null) {
ourInstance = new RequestManager(context);
} else {
throw new IllegalArgumentException("Context must be set");
}
}
return ourInstance;
}
public static RequestManager getInstance() {
return ourInstance;
}
private RequestManager(Context context) {
requestQueue = Volley.newRequestQueue(context);
imageLoader = new ImageLoader(
requestQueue,
new ImageLoader.ImageCache() {
private LruCache<String, Bitmap> 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 RequestQueue getRequestQueue() {
return requestQueue;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
application:
package com.ht.xiangqu.util;
import android.app.Application;
import android.util.Log;
/** * Created by annuo on 2015/6/16.
*/
publicclassMainApplation extends Application {
@OverridepublicvoidonCreate() {
super.onCreate();
RequestManager.createInstance(getApplicationContext());
Log.d("nihao","nihao"); }
}
2、內存緩存
只有加載圖片的時候纔會有內存緩存,對於字符串一般都是之後文件緩存。
google並沒有自動的幫我們實現內存的緩存,需要我們自己手動加入進去。內存緩存在單例類中已經體現了(即LruCache),以後我們每次使用的時候都不必再加入內存緩存。LruCache這個類是Android3.1版本中提供的,如果你是在更早的Android版本中開發,則需要導入android-support-v4的jar包。
3、文件緩存
volley已經默認幫我們實現了文件的緩存。我們通過源代碼看一下:
/**
* Constructs a new ImageLoader.
* @param queue The RequestQueue to use for making image requests.
* @param imageCache The cache to use as an L1 cache.
*/
public ImageLoader(RequestQueue queue, ImageCache imageCache) {
mRequestQueue = queue;
mCache = imageCache;
}
以上代碼是imageloader中的一段代碼,從中我們可以看到在構造imageloader時,我們已經默認的建立了一個L1級的緩存(文件緩存)。
那volley緩存下來的文件到底在哪呢?見下圖:
具體的位置就在如圖所示的位置。即data/data/應用程序的包名/volley,如果沒有修改volley的緩存位置,默認名字叫volley。
4、圖片的二次採樣的問題
其實volley默認的已經幫我們做了圖片的二次採樣,只是需要我們在進行請求的時候,多加入兩個參數。我們一般都忽略了這個問題,最後導致的是不斷的OOM。
/**
* 這是訪問網絡圖片的核心方法
* @param requestUrl
* @param imageListener
* @param maxWidth
* @param maxHeight
* @return
*/
public ImageContainer get(String requestUrl, ImageListener imageListener,
int maxWidth, int maxHeight) {
<span style="white-space:pre"> </span>Request<?> newRequest =
new ImageRequest(requestUrl, new Listener<Bitmap>() {
@Override
public void onResponse(Bitmap response) {
onGetImageSuccess(cacheKey, response);
}
}, maxWidth, maxHeight,
Config.RGB_565, new ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
onGetImageError(cacheKey, error);
}
});
mRequestQueue.add(newRequest);
mInFlightRequests.put(cacheKey,
new BatchedImageRequest(newRequest, imageContainer));
return imageContainer;
}
以上代碼是imageloader的核心方法,其中有兩個參數是maxWidth,maxHeight,我們一般都忽略了這兩個參數。默認值是0和0,這樣二次採樣算法就不起作用了,我們得到的圖片是從服務器1:1哪來的。但是一般我們設置了這兩個參數,就可以得到我們希望的縮小比例的圖片。這樣就可以完全的避免OOM。
三、volley的其他問題
1、圓角圖片的問題
public static ImageListener getImageListener(final ImageView view,
final int defaultImageResId, final int errorImageResId) {
return new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (errorImageResId != 0) {
view.setImageResource(errorImageResId);
}
}
@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null) {
//在這裏可以設置,如果想得到圓角圖片的畫,可以對bitmap進行加工,可以給imageview加一個
//額外的參數
view.setImageBitmap(response.getBitmap());
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}
2、listview複用時,解決圖片錯位的問題
/**
* 使用此方法能夠解決圖片錯亂問題
* @param view
* @param defaultImageResId
* @param errorImageResId
* @param url
* @return
*/
public static ImageListener getImageListener(
final ImageView view,
final int defaultImageResId,
final int errorImageResId,
final String url) {
return new ImageListener() {
@Override
public void onErrorResponse(VolleyError error) {
if (errorImageResId != 0) {
view.setImageResource(errorImageResId);
}
}
@Override
public void onResponse(ImageContainer response, boolean isImmediate) {
if (response.getBitmap() != null) {
//在這裏可以設置,如果想得到圓角圖片的畫,可以對bitmap進行加工,可以給imageview加一個
//額外的參數
String urlTag = (String) view.getTag();
if(urlTag!=null && urlTag.trim().equals(url)){
view.setImageBitmap(response.getBitmap());
}
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}
四、volley的具體用法
關於這塊內容,網絡上有很多的資料,總之volley使用起來非常的簡單,感興趣的可以去網絡上查找相關的資料進行學習。volley的加載速度絕對出乎你的意料。
——知道自己是誰,要什麼,能跳多高,而且敢跳,並承受跳了可能失敗的所有結果。