Android图片异步加载_异步加载

分享到:

开发Android程序,一般情况下都会有两个操作,图片的异步加载与缓存,而图片的异步加载大都是从网络读取图片(还有生成本地图片缩略图等操作),为了减少网络操作,加快图片加载速度就需要对图片进行缓存,所以网上的好多图片异步加载方法都是与图片的缓存紧密关联的。但也有可能用户已经有了缓存的相关类库,这样使用起来就会有点麻烦。

最近一段处理跟图片相关的问题,本来是自己写的图片加载,不过有些状态的控制还是比较烦人的,比如ListView滚动时ImageView的重用,所以本着偷懒与充分利用现有资源的态度去网上搜罗图片异步加载的代码,最终在GreenDroid UI库中找到一个,其中有个AsyncImageView的自定义View用于异步加载图片,不过也像网上的大多数图片异步加载方法一样,是跟图片的缓存关联在一起的,不过只是很简单的内存缓存,无文件缓存。图片的加载方法也如其他的一样是写死了的,这就限制了其使用范围,只可通过InputStream来decode图片,而像生成缩略图或其他一些图片处理的异步处理就无法用途。修改现有类库总比自己从头写来的简单,于是稍微修改了下AsyncImageView,使其可以自定义缓存与图片加载方法,对于AsyncImageView只有一点点的修改,大都是别人源码。

1. 核心类

  • ImageLoader:图片加载核心类,内部使用线程池加载图片
  • ImageRequest:表示一个图片加载的请求
  • AsyncImageView:自定义的图片异步加载View
  • LoadMethod:自定义图片加载方法的接口,可以通过实现此接口来自定义图片的加载方法
  • CacheCallback:缓存接口,可以通过实现此接口实现对缓存的读写
  • AsyncImageView.OnImageViewLoadListener:图片加载状态监听(开始,失败,结束)

2. 图片加载方法

public void run() {      Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);      final Handler h = mHandler;     Bitmap bitmap = null;     Throwable throwable = null;      h.sendMessage(Message.obtain(h, ON_START));      try {         if (TextUtils.isEmpty(mUrl)) {             throw new Exception("The given URL cannot be null or empty");         }          // 如果自定义了加载方法,则用自定义的方法
        if (mLoadMethod != null) {             bitmap = mLoadMethod.load(mUrl);         } else {              InputStream inputStream = null;              // Asset
            if (mUrl.startsWith("file:///android_asset/")) {                 inputStream = sAssetManager.open(mUrl.replaceFirst(                         "file:///android_asset/", ""));             }             // File
            else if (mUrl.startsWith("file:///") || mUrl.startsWith("/")) {                 if (mUrl.startsWith("file:///"))                     mUrl = mUrl.replaceFirst("file:///", "/");                 inputStream = new FileInputStream(mUrl);             }             // NetWork
            else {                 // 在用URL类加载图片时,发现有的机型上面通过URL类获得的InputStream解析获得的图片总是null,故使用HttpClient
                HttpGet httpRequest = new HttpGet(mUrl);                 HttpClient httpclient = new DefaultHttpClient();                 HttpParams httpParams = new BasicHttpParams();                 HttpConnectionParams.setConnectionTimeout(httpParams, 5000);                 HttpConnectionParams.setSoTimeout(httpParams, 5000);                 httpRequest.setParams(httpParams);                 HttpResponse response = (HttpResponse)httpclient.execute(httpRequest);                 HttpEntity entity = response.getEntity();                 BufferedHttpEntity bufHttpEntity = new BufferedHttpEntity(entity);                 InputStream instream = bufHttpEntity.getContent();                 BufferedInputStream bi = new BufferedInputStream(instream);                 inputStream = bi;             }              // 虽然AsyncImageView中有设置BitmapFactory.Options的方法,但一般情况下都未知图片的大小,也就无法计算相应的inSampleSize,             // 也就无法设置相应的BitmapFactory.Options,所以一般情况下还是根据自己的需要自定义LoadMethod为好
            bitmap = BitmapFactory.decodeStream(inputStream, null,                     (mOptions == null) ? sDefaultOptions : mOptions);             inputStream.close();         }         if (mBitmapProcessor != null && bitmap != null) {             final Bitmap processedBitmap = mBitmapProcessor.processImage(bitmap);             if (processedBitmap != null) {                 bitmap.recycle();                 bitmap = processedBitmap;             }         }      } catch (Exception e) {         Log.e(LOG_TAG, "Error while fetching image", e);         throwable = e;     }      if (bitmap == null) {         if (throwable == null) {             throwable = new Exception("Skia image decoding failed");         }         h.sendMessage(Message.obtain(h, ON_FAIL, throwable));     } else {         h.sendMessage(Message.obtain(h, ON_END, bitmap));         if (mCache != null) {             mCache.writeCache(TextUtils.isEmpty(mCacheKey) ? mUrl : mCacheKey, bitmap);         }     } }
昵    称:
验证码: