Android 自定义本地图片加载库,仿微信相册

本文介绍了如何实现一个仿微信相册的本地图片加载库,重点在于提高用户体验,包括逐个加载缩略图、快速滑动时的智能加载策略、已加载图片的缓存复用等。通过调整图片分辨率、使用LRU缓存、定制线程池和读取Exif信息来优化加载过程。项目源码已上传至GitHub。
摘要由CSDN通过智能技术生成

总结一下微信的本地图片加载有以下几个特点,也是提高用户体验的关键点

1、缩略图挨个加载,一个一个加载完毕,直到屏幕所有缩略图都加载完成

2、不等当前屏的所有缩略图加载完,迅速向下滑,滑动停止时立即加载停止页面的图片

3、已经加载成功的缩略图,不管滑出去多远,滑回来的时候不需要重新加载

4、在相册以外的环境中,需要让imageView的宽高比例随图片的宽高比例自动伸缩,而且要在图片加载完毕之前就要预留占位空间

为了满足上面几个要求,主要采用以下几个方法:

0、为了防止图片加载出来OOM,需要对分辨率和颜色的位数进行缩小到合适范围,同时采用LRU缓存

1、采用一个定长线程池,线程池的大小等于CPU的数量+1,把所有缩略图加载任务都交给线程池执行,以获得最快的加载效率。

2、在用户快速滑动的时候,没有加载完毕的划走了的图片立即停止加载,将所占线程让出来,让新的加载任务执行。

3、已经加载成功的缩略图,保存到sd卡中,下次再滑动回来的时候,直接从sd卡加载以前保存好的小图,不经过线程池。

4、对于三星这样的手机,其图片全都是宽度大于高度,方向用exif进行记录,图片加载器要读出exif的方向信息,然后通过矩阵进行旋转

效果展示:


github项目地址:https://github.com/AlexZhuo/AlxImageLoader

下面就是加载器主要部分的注释和代码

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import android.graphics.Matrix;
import android.media.ExifInterface;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.demo.task.AlxMultiTask;


/**
 * Created by Administrator on 2016/4/8.
 */
public class AlxImageLoader {

    private Context mcontext;
    private HashMap<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();
    private ConcurrentHashMap<ImageView,String> currentUrls = new ConcurrentHashMap<>();//记录一个imageView应该显示哪个Url,用于中断子线程
    private Bitmap defbitmap;

        public AlxImageLoader(Context context) {
            this.mcontext = context;
            defbitmap = BitmapFactory.decodeResource(mcontext.getResources(), R.drawable.upload_photo4x);//没加载到图片的默认显示
        }

    /**
     * 从本地加载一张图片并使用imageView进行显示,可以设置是否根据图片的大小动态修改imageView的高度,宽度必须传入来控制显示图片的清晰度防止oom
     * @param uri
     * @param imageView
     * @param imageViewWidth
     * @param resizeImageView
     * @param autoRotate
     * @param imageCallback
     * @return
     */
     private Bitmap loadBitmapFromSD(final String uri, final ImageView imageView, final int imageViewWidth, final boolean resizeImageView, final boolean autoRotate,final boolean storeThumbnail ,final ImageCallback imageCallback) {
         if (imageCache.containsKey(uri)) {//如果之前已经加载过这个图片,那么就从LRU缓存里加载
             SoftReference<Bitmap> SoftReference = imageCache.get(uri);
             Bitmap bitmap = SoftReference.get();
             if (bitmap != null) {
                 Log.i("Alex","现在是从LRU中拿出来的bitmap");
                 return bitmap;//从系统内存里直接拿出来
             }
         }

         final int[] imageSize = {0,0};
         if(uri ==null)return null;
         if(storeThumbnail) {
             File file = new File(imageView.getContext().getCacheDir().getAbsolutePath().concat("/" + new File(uri).getName()));
             if (file.exists() && file.length()>1000) {
                 //因为从file中获取图片的宽高存在IO操作,所以把每个图片的宽高缓存起来
                 Log.i("Alex", "现在是从
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值