Volley下载网络图片使用步骤级相关源码
2016-03-27 22:43
260 查看
一、Volley下载网络图片使用步骤(四步):
1 创建一个请求队列:2 创建一个下载图片的监听器:
3 创建缓存
4 根据url获取图片
二 创建一个请求队列:
创建请求队列RequestQueue代码:mQueue = Volley.newRequestQueue(this);
详细代码如下:
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR); String userAgent = "volley/0"; try { String packageName = context.getPackageName(); PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0); userAgent = packageName + "/" + info.versionCode; } catch (NameNotFoundException e) { } if (stack == null) { if (Build.VERSION.SDK_INT >= 9) { stack = new HurlStack(); } else { // Prior to Gingerbread, HttpUrlConnection was unreliable. // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent)); } } Network network = new BasicNetwork(stack); RequestQueue queue; if (maxDiskCacheBytes <= -1) { // No maximum size specified queue = new RequestQueue(new DiskBasedCache(cacheDir), network); } else { // Disk cache size specified queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network); } queue.start(); return queue;
queue.start():启动代码:
public void start() { stop(); // Make sure any currently running dispatchers are stopped. // Create the cache dispatcher and start it. mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery); mCacheDispatcher.start(); // Create network dispatchers (and corresponding threads) up to the pool size. for (int i = 0; i < mDispatchers.length; i++) { NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork, mCache, mDelivery); mDispatchers[i] = networkDispatcher; networkDispatcher.start(); }
CacheDispathcer是一个线程,start()代码
public void run() { if (DEBUG) VolleyLog.v("start new dispatcher"); Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); // Make a blocking call to initialize the cache. mCache.initialize(); while (true) { try { // Get a request from the cache triage queue, blocking until // at least one is available. final Request<?> request = mCacheQueue.take(); request.addMarker("cache-queue-take"); // If the request has been canceled, don't bother dispatching it. if (request.isCanceled()) { request.finish("cache-discard-canceled"); continue; } // Attempt to retrieve this item from cache. Cache.Entry entry = mCache.get(request.getCacheKey()); if (entry == null) { request.addMarker("cache-miss"); // Cache miss; send off to the network dispatcher. mNetworkQueue.put(request); continue; } // If it is completely expired, just send it to the network. if (entry.isExpired()) { request.addMarker("cache-hit-expired"); request.setCacheEntry(entry); mNetworkQueue.put(request); continue; } // We have a cache hit; parse its data for delivery back to the request. request.addMarker("cache-hit"); Response<?> response = request.parseNetworkResponse( new NetworkResponse(entry.data, entry.responseHeaders)); request.addMarker("cache-hit-parsed"); if (!entry.refreshNeeded()) { // Completely unexpired cache hit. Just deliver the response. mDelivery.postResponse(request, response); } else { // Soft-expired cache hit. We can deliver the cached response, // but we need to also send the request to the network for // refreshing. request.addMarker("cache-hit-refresh-needed"); request.setCacheEntry(entry); // Mark the response as intermediate. response.intermediate = true; // Post the intermediate response back to the user and have // the delivery then forward the request along to the network. mDelivery.postResponse(request, response, new Runnable() { @Override public void run() { try { mNetworkQueue.put(request); } catch (InterruptedException e) { // Not much we can do about this. } } }); } } catch (InterruptedException e) { // We may have been interrupted because it was time to quit. if (mQuit) { return; } continue; } } }
三、创建一个下载图片的监听器:
imgListener = ImageLoader.getImageListener(imgImageView, 0,
R.drawable.mz_img_error)
详细代码如下:直接调用了ImageView的setImageResource。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); } } };
四、创建缓存
mImageLoader = new ImageLoader(mQueue, new BitmapCache());
public ImageLoader(RequestQueue queue, ImageCache imageCache) {
mRequestQueue = queue;
mCache = imageCache;
}
五、根据url获取图片
获取图片:// 4 获得图片 mImageLoader.get(Images.imageUrls[0], imgListener);
调用如下代码:
public ImageContainer get(String requestUrl, final ImageListener listener) { return get(requestUrl, listener, 0, 0); }
继续调用:
public ImageContainer get(String requestUrl, ImageListener imageListener, int maxWidth, int maxHeight) { return get(requestUrl, imageListener, maxWidth, maxHeight, ScaleType.CENTER_INSIDE); }
实际上调用的还是ImageLoader的:
public ImageContainer get(String requestUrl, ImageListener imageListener, int maxWidth, int maxHeight, ScaleType scaleType) { // only fulfill requests that were initiated from the main thread. throwIfNotOnMainThread(); //计算缓存Key final String cacheKey = getCacheKey(requestUrl, maxWidth, maxHeight, scaleType); // Try to look up the request in the cache of remote images.尝试从缓存中获取图像资源 Bitmap cachedBitmap = mCache.getBitmap(cacheKey); if (cachedBitmap != null) { // Return the cached bitmap. 如果缓存中有则直接获取,请求结束 ImageContainer container = new ImageContainer(cachedBitmap, requestUrl, null, null); imageListener.onResponse(container, true); return container; } // 缓存中没有则下载之 // The bitmap did not exist in the cache, fetch it! 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.//判断该url是否正在被请求 BatchedImageRequest request = mInFlightRequests.get(cacheKey); if (request != null) { // If it is, add this request to the list of listeners. request.addContainer(imageContainer); return imageContainer; } // The request is not already in flight. Send the new request to the network and // track it. Request<Bitmap> newRequest = makeImageRequest(requestUrl, maxWidth, maxHeight, scaleType, cacheKey); mRequestQueue.add(newRequest); mInFlightRequests.put(cacheKey, new BatchedImageRequest(newRequest, imageContainer)); return imageContainer; }
其他相关类:
ImageContainer:用于保存图像队列的所有数据,即已下载的图片资源,该类是ImageLoader的内部类
/** * Container object for all of the data surrounding an image request. */ 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; /** The request URL that was specified */ private final String mRequestUrl; /** * Constructs a BitmapContainer object. * @param bitmap The final bitmap (if it exists). * @param requestUrl The requested URL for this container. * @param cacheKey The cache key that identifies the requested URL for this container. */ public ImageContainer(Bitmap bitmap, String requestUrl, String cacheKey, ImageListener listener) { mBitmap = bitmap; mRequestUrl = requestUrl; mCacheKey = cacheKey; mListener = listener; } /** * Releases interest in the in-flight request (and cancels it if no one else is listening). */ public void cancelRequest() { if (mListener == null) { return; } BatchedImageRequest request = mInFlightRequests.get(mCacheKey); if (request != null) { boolean canceled = request.removeContainerAndCancelIfNecessary(this); if (canceled) { mInFlightRequests.remove(mCacheKey); } } else { // check to see if it is already batched for delivery. request = mBatchedResponses.get(mCacheKey); if (request != null) { request.removeContainerAndCancelIfNecessary(this); if (request.mContainers.size() == 0) { mBatchedResponses.remove(mCacheKey); } } } } /** * Returns the bitmap associated with the request URL if it has been loaded, null otherwise. */ public Bitmap getBitmap() { return mBitmap; } /** * Returns the requested URL for this container. */ public String getRequestUrl() { return mRequestUrl; } }
参考:
Android 网络通信框架Volley简介(Google IO 2013)http://blog.csdn.net/onlysnail/article/details/47905375
Volley源码解析:
相关文章推荐
- 网络协议之DHCP request续约实现机制
- 从C10K到C10M高性能网络的探索与实践
- 20159311《网络攻击与防范》第四周学习总结
- TCP/IP五层网络架构
- C#网络编程之多线程socket实例
- httpclient 4.5.1---http工具类
- httpclient 4.5.1---连接管理器
- 使用SOCKET实现TCP/IP协议的通讯
- httpclient 4.5.1---高级主题
- http请求的理解
- httpclient 4.5.1---状态管理
- httpclient 4.5.1---连接管理
- CCF 无线网络
- httpclient 4.5.1---流式API使用
- 网络的可靠性(nyoj)
- httpclient 4.5.1---基础
- TCP/IP
- 卷积神经网络CNN(Convolutional Neural Networks)没有原理只有实现
- 使用java进行http通信
- Linux网络配置