<span style="font-size:18px;">/**
*
* Volley是Android平台网络通信库:更快。更简单。更健壮 volley提供的功能: 1.JSON、图片(异步) 2.网络请求的排序
* 3.网络请求的优先级处理 4.缓存 5.多级别的取消请求 6.与Activity生命周期联动
* 适合网络请求频换,数据量不是很大的 网络请求****
*
* 获取Volley git clone
* https://android.googlesource.com/platform/frameworks/volley
*
*
*
*
*
*/
public class MainActivity extends Activity {
private ImageView iv1;
private NetworkImageView iv2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
getJSONVolley();
}
public void init() {
iv1 = (ImageView) findViewById(R.id.iv);
iv2 = (NetworkImageView) findViewById(R.id.imageView1);
loadImageVolley();
NetWorkImageViewVolley();
}
// 获取json字符串
public void getJSONVolley() {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String JSONDateUrl = "http://www.wwtliu.com/jsondata.html";
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.GET, JSONDateUrl, null,
new Response.Listener<JSONObject>() {
public void onResponse(JSONObject response) {
System.out.println("response=" + response);
}
}, new Response.ErrorListener() {
public void onErrorResponse(
com.android.volley.VolleyError arg0) {
System.out.println("对不起,有问题");
}
});
requestQueue.add(jsonObjectRequest);
}
// http://localhost/lesson-img.png
public void loadImageVolley() {
String imageurl = "http://10.0.0.52/lesson-img.png";
RequestQueue requestQueue = Volley.newRequestQueue(this);
final LruCache<String, Bitmap> lurcache = new LruCache<String, Bitmap>(
20);
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
lurcache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return lurcache.get(key);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
ImageListener listener = imageLoader.getImageListener(iv1,
R.drawable.ic_launcher, R.drawable.ic_launcher);
imageLoader.get(imageurl, listener);
}
public void NetWorkImageViewVolley(){
String imageUrl = "http://10.0.0.52/lesson-img.png";
RequestQueue requestQueue = Volley.newRequestQueue(this);
final LruCache<String, Bitmap> lruCache = new LruCache<String, Bitmap>(20);
ImageCache imageCache = new ImageCache() {
@Override
public void putBitmap(String key, Bitmap value) {
lruCache.put(key, value);
}
@Override
public Bitmap getBitmap(String key) {
return lruCache.get(key);
}
};
ImageLoader imageLoader = new ImageLoader(requestQueue, imageCache);
iv2.setTag("url");
iv2.setImageUrl(imageUrl, imageLoader);
}
}
</span>
tv1 设置图片的方法 看源代码:
<span style="font-size:18px;"> public ImageLoader(RequestQueue queue, ImageCache imageCache) {
mRequestQueue = queue;
mCache = imageCache;
}</span>
初始化imageloader
<span style="font-family:Arial;font-size:18px;BACKGROUND-COLOR: #ffffff"></span>
<span style="font-size:18px;"> public class ImageContainer {
/**
* The most relevant bitmap for the container. If the image was in cache, the
* Holder to use for the final bitmap (the one that pairs to the requested URL).
*/
private Bitmap mBitmap;图片
private final ImageListener mListener;监听
/** The cache key that was associated with the request */
private final String mCacheKey;缓存的key
/** The request URL that was specified */
private final String mRequestUrl;请求URL
</span>
ImageContainer 封装了图片和 监听 key URL
<span style="font-size:18px;"> 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) {
view.setImageBitmap(response.getBitmap());
} else if (defaultImageResId != 0) {
view.setImageResource(defaultImageResId);
}
}
};
}</span>
onResponse(ImageContainer response, boolean isImmediate) 传进来 ImageContainer 参数
<span style="font-size:18px;"> public ImageContainer get(String requestUrl, ImageListener imageListener,
int maxWidth, int maxHeight) {
// only fulfill requests that were initiated from the main thread.
throwIfNotOnMainThread();
final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight);
// Try to look up the request in the cache of remote images.
Bitmap cachedBitmap = mCache.getBitmap(cacheKey);
//如果缓存有图片
if (cachedBitmap != null) {
ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null);
//回调给 监听 返回缓存的图片
imageListener.onResponse(container, true);
return container;
}
//如果无缓存图片
ImageContainer imageContainer =
new ImageContainer(null, requestUrl, cacheKey, imageListener);
// Update the caller to let them know that they should use the default bitmap.
imageListener.onResponse(imageContainer, true);
// Check to see if a request is already in-flight.
BatchedImageRequest request = mInFlightRequests.get(cacheKey);
if (request != null) {
// If it is, add this request to the list of listeners.
request.addContainer(imageContainer);
return imageContainer;
}
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;
}</span>
final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight); 用URL 生成一个 唯一标识的key
Bitmap cachedBitmap = mCache.getBitmap(cacheKey); 获取缓图片
接着 判断是否cachedBitmap!=null 是的话构造ImageContainer 将图片和URL封装起来。
ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null);
//调用imagelistener监听方法传递 封装好的ImageContainer
imageListener.onResponse(container, true);
如果没缓存图片
ImageContainer imageContainer = new ImageContainer(null, requestUrl, cacheKey, imageListener);
imageListener.onResponse(imageContainer, true);
第一个参数Bitmap 为null 封装URL key image监听 其实就是回调接口 ImageView设置默认图片
接着BatchedImageRequest request = mInFlightRequests.get(cacheKey); 判断这个集合是否有这个请求 用于
如果request !=null
request.addContainer(imageContainer);
return imageContainer;上面例子iv2 返回 imageContainer
接下来代码
<span style="font-size:18px;">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);
}
});</span>
因为缓存没图片 说明第一次请求或者删除了 。重新构造请求
onGetImageSuccess(cacheKey, response);
<span style="font-size:18px;">mRequestQueue.add(newRequest);
mInFlightRequests.put(cacheKey, new BatchedImageRequest(newRequest, imageContainer));</span>
然后 添加到请求队列 和mInFlightRequests 集合中 new BatchedImageRequest的时候
<span style="font-size:18px;"> public BatchedImageRequest(Request<?> request, ImageContainer container) {
mRequest = request;
mContainers.add(container);
}
</span>
把ImageContainer 加到BatchedImageRequest 类成员变量 集合中
<span style="font-size:18px;"> /**
* Handler for when an image was successfully loaded.
* @param cacheKey The cache key that is associated with the image request.
* @param response The bitmap that was returned from the network.
*/
private void onGetImageSuccess(String cacheKey, Bitmap response) {
// cache the image that was fetched.
mCache.putBitmap(cacheKey, response);
// remove the request from the list of in-flight requests.
BatchedImageRequest request = mInFlightRequests.remove(cacheKey);
if (request != null) {
// Update the response bitmap.
request.mResponseBitmap = response;
// Send the batched response
batchResponse(cacheKey, request);
}
}</span>
mCache.putBitmap(cacheKey, response); 把图片缓存起来
mInFlightRequests这个请求hasmap中是否已经包含你想要下载的图片,如果有,将这个请求加入到批量处理的请求(BatchedImageRequest)中, 为什么要这样做?其实volley是想帮你解决这样一种情况:假如有2个地方都需要下载同样的图片,而这张图片并没有下载完成(也就是说没办法去缓存中取图片数据),那么volley就会把这两个请求都保存起来,当下载完成后,统一返回给这2个请求的view,这样就不需要下载2遍重复的请求
<span style="font-size:18px;">private void batchResponse(String cacheKey, BatchedImageRequest request) {
mBatchedResponses.put(cacheKey, request);
// If we don't already have a batch delivery runnable in flight, make a new one.
// Note that this will be used to deliver responses to all callers in mBatchedResponses.
if (mRunnable == null) {
mRunnable = new Runnable() {
@Override
public void run() {
//遍历 批处理request
for (BatchedImageRequest bir : mBatchedResponses.values()) {
for (ImageContainer container : bir.mContainers) {
// If one of the callers in the batched request canceled the request
// after the response was received but before it was delivered,
// skip them.
if (container.mListener == null) {
continue;
}
if (bir.getError() == null) {
container.mBitmap = bir.mResponseBitmap;
container.mListener.onResponse(container, false);
} else {
container.mListener.onErrorResponse(bir.getError());
}
}
}
mBatchedResponses.clear();
mRunnable = null;
}
};
// Post the runnable.
mHandler.postDelayed(mRunnable, mBatchResponseDelayMs);
}
}</span>
container.mBitmap = bir.mResponseBitmap;
变量得到请求中的ImageContainer
container.mListener.onResponse(container, false);