Android远程图片获取和本地缓存

 

先定义A缓存:
?
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
    private final HashMap<String, Bitmap>mHardBitmapCache = new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY/ 2 , 0 .75f, true ) {
    @Override
    protected booleanremoveEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
    if (size() >HARD_CACHE_CAPACITY) {
    //当map的size大于30时,把最近不常用的key放到mSoftBitmapCache中,从而保证mHardBitmapCache的效率
    mSoftBitmapCache.put(eldest.getKey(), newSoftReference<Bitmap>(eldest.getValue()));
    return true ;
    } else
    return false ;
    }
    };


再定于B缓存:
?
代码片段,双击复制
01
02
03
04
05
    /**
    *当mHardBitmapCache的key大于30的时候,会根据LRU算法把最近没有被使用的key放入到这个缓存中。
    *Bitmap使用了SoftReference,当内存空间不足时,此cache中的bitmap会被垃圾回收掉
    */
    private final staticConcurrentHashMap<String, SoftReference<Bitmap>> mSoftBitmapCache = new ConcurrentHashMap<String,SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2 );

从缓存中获取数据:
?
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
    /**
    * 从缓存中获取图片
    */
    private Bitmap getBitmapFromCache(Stringurl) {
    // 先从mHardBitmapCache缓存中获取
    synchronized (mHardBitmapCache) {
    final Bitmap bitmap =mHardBitmapCache.get(url);
    if (bitmap != null ) {
    //如果找到的话,把元素移到linkedhashmap的最前面,从而保证在LRU算法中是最后被删除
    mHardBitmapCache.remove(url);
    mHardBitmapCache.put(url,bitmap);
    return bitmap;
    }
    }
    //如果mHardBitmapCache中找不到,到mSoftBitmapCache中找
    SoftReference<Bitmap>bitmapReference = mSoftBitmapCache.get(url);
    if (bitmapReference != null ) {
    final Bitmap bitmap =bitmapReference.get();
    if (bitmap != null ) {
    return bitmap;
    } else {
    mSoftBitmapCache.remove(url);
    }
    }
    return null ;
    }


如果缓存中不存在,那么就只能去服务器端去下载:

?
代码片段,双击复制
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
    * 异步下载图片
    */
    class ImageDownloaderTask extendsAsyncTask<String, Void, Bitmap> {
    private static final int IO_BUFFER_SIZE= 4 * 1024 ;
    private String url;
    private finalWeakReference<ImageView> imageViewReference;
    public ImageDownloaderTask(ImageViewimageView) {
    imageViewReference = newWeakReference<ImageView>(imageView);
    }
    @Override
    protected BitmapdoInBackground(String... params) {
    final AndroidHttpClient client =AndroidHttpClient.newInstance( "Android" );
    url = params[ 0 ];
    final HttpGet getRequest = newHttpGet(url);
    try {
    HttpResponse response =client.execute(getRequest);
    final int statusCode =response.getStatusLine().getStatusCode();
    if (statusCode !=HttpStatus.SC_OK) {
    Log.w(TAG, "从" +url + "中下载图片时出错!,错误码:" + statusCode);
    return null ;
    }
    final HttpEntity entity =response.getEntity();
    if (entity != null ) {
    InputStream inputStream = null ;
    OutputStream outputStream = null ;
    try {
    inputStream =entity.getContent();
    finalByteArrayOutputStream dataStream = new ByteArrayOutputStream();
    outputStream = newBufferedOutputStream(dataStream, IO_BUFFER_SIZE);
    copy(inputStream,outputStream);
    outputStream.flush();
    final byte [] data =dataStream.toByteArray();
    final Bitmap bitmap =BitmapFactory.decodeByteArray(data, 0 , data.length);
    return bitmap;
    } finally {
    if (inputStream != null ) {
    inputStream.close();
    }
    if (outputStream != null ) {
    outputStream.close();
    }
    entity.consumeContent();
    }
    }
    } catch (IOException e) {
    getRequest.abort();
    Log.w(TAG, "I/O errorwhile retrieving bitmap from " + url, e);
    } catch (IllegalStateException e) {
    getRequest.abort();
    Log.w(TAG, "Incorrect URL:" + url);
    } catch (Exception e) {
    getRequest.abort();
    Log.w(TAG, "Error whileretrieving bitmap from " + url, e);
    } finally {
    if (client != null ) {
    client.close();
    }
    }
    return null ;
    }

 

这是两种做法,还有一些应用在下载的时候使用了线程池和消息队列MQ,对于图片下载的效率要更好一些。有兴趣的同学可以看下。

总结
对于远程图片等相对比较大的资源一定要在异步线程中去获取本地做缓存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值