加载图片工具类

来源:互联网 发布:淘宝关键词提取工具 编辑:程序博客网 时间:2024/06/07 05:33

使用HandlerThread实现的加载,HandlerThread中定义了线程、调用了Looper.prepare()和Looper.loop()方法。与Handler绑定后,loop()方法循环从MessageQueue中取Handler发送来的消息进行图片加载。

直接上代码:

/** * 加载图片核心类,可以拷贝直接用 * @Description: TODO * @author 张永飞 * @date 2016-6-11  * */public class ImageLoader {    private static ImageLoader mInstance;    // 队列调度方式: 后进先出    public static final int LIFO = 0;    // 队列调度方式: 先进先出    public static final int FIFO = 1;    private Handler mThreadHandler;    // 队列调度方式    private int mType;    // 线程池    private ExecutorService mThreadPool;    // 控制线程资源的信号量    private volatile Semaphore mPoolSemaphore;    // 任务队列链表    private LinkedList<Runnable> mTaskQueue;    private LruCache<String, Bitmap> mLruCache;    private Handler mUIHandler;    // 是否开启本地磁盘缓存    private static final boolean isDiskCacheEnable = true;    public static ImageLoader getInstance(int threadCount, int type) {        if (mInstance == null) {            synchronized (ImageLoader.class) {                if (mInstance == null) {                    mInstance = new ImageLoader(threadCount, type);                }            }        }        return mInstance;    }    private ImageLoader(int threadCount, int type) {        initBackThread();        initLruCache();        mType = type;        mTaskQueue = new LinkedList<Runnable>();        mThreadPool = Executors.newFixedThreadPool(threadCount);        mPoolSemaphore = new Semaphore(threadCount);    }    private void initBackThread() {        HandlerThread handlerThread = new HandlerThread("image-loader-thread");        handlerThread.start();        mThreadHandler = new Handler(handlerThread.getLooper()) {            public void handleMessage(Message msg) {                try {                    mPoolSemaphore.acquire();                    mThreadPool.execute(getTask());                } catch (Exception e) {                    e.printStackTrace();                }            };        };    }    private void initLruCache() {        // 进程可以从虚拟机获取的最大可用内存        int maxMemory = (int) Runtime.getRuntime().maxMemory();        int cacheSize = maxMemory / 8;        mLruCache = new LruCache<String, Bitmap>(cacheSize){            @Override            protected int sizeOf(String key, Bitmap value) {                // 图片的行字节数 * 图片的高度 = 图片的字节数                return value.getRowBytes() * value.getHeight();            }        };    }    /**     * 根据路径设置图片到对应的ImageView上     * @param path 图片全路径名,可以是URL     * @param imageView 显示图片的控件     * @param isFromNet 是否从网络下载     */    public void loadImage(final String path, final ImageView imageView,            final boolean isFromNet) {        imageView.setTag(path);        if (mUIHandler == null) {            mUIHandler = new Handler() {                public void handleMessage(Message msg) {                    ImageBeanHolder holder = (ImageBeanHolder) msg.obj;                    ImageView imageView2 = holder.imageView;                    Bitmap bitmap2 = holder.bitmap;                    String path2 = holder.path;                    // 防止图片错位                    if (imageView2.getTag().toString().equals(path2)) {                        imageView2.setImageBitmap(bitmap2);                    }                };            };        }        Bitmap bitmap = getBitmapFromLruCache(path);        if (bitmap != null) {            sendMsgToUIHandler(path, imageView, bitmap);        } else {            addTask(buildTask(path, imageView, isFromNet));        }    }    private synchronized void addTask(Runnable runnable) {        mTaskQueue.add(runnable);        mThreadHandler.sendEmptyMessage(0);    }    private synchronized Runnable getTask() {        Runnable result = null;        if (mType == LIFO) {            result = mTaskQueue.removeLast();        } else if (mType == FIFO) {            result = mTaskQueue.removeFirst();        }        return result;    }    private Runnable buildTask(final String path, final ImageView imageView,            final boolean isFromNet) {        return new Runnable() {            @Override            public void run() {                Bitmap bitmap = null;                if (isFromNet) {                    bitmap = loadImageFromUrl(path, imageView);                } else {                    bitmap = loadImageFromLocal(path, imageView);                }                putBitmapToLruCache(path, bitmap);                sendMsgToUIHandler(path, imageView, bitmap);                mPoolSemaphore.release();            }        };    }    private Bitmap loadImageFromUrl(String path, ImageView imageView) {        File picDiskCacheFile = getPicDiskCacheFile(imageView.getContext(),                getFileMD5(path));        Bitmap bitmap = null;        if (picDiskCacheFile.exists()) {            bitmap = loadImageFromLocal(picDiskCacheFile.getAbsolutePath(),                    imageView);        } else {            if (isDiskCacheEnable) {                boolean isSuccess = downloadUrlPic(path, picDiskCacheFile);                if (isSuccess) {                    bitmap = loadImageFromLocal(                            picDiskCacheFile.getAbsolutePath(), imageView);                } else {                    System.out.println(picDiskCacheFile.getAbsolutePath()                            + "下载失败,删除");                    picDiskCacheFile.delete();                }            } else {                bitmap = loadUrlBitmap(path, imageView);            }        }        return bitmap;    }    private Bitmap loadImageFromLocal(String path, ImageView imageView) {        ImageViewSize imageViewSize = getImageViewSize(imageView);        return decodeThumbnailFromResource(path, imageViewSize);    }    // 从网络下载图片    private boolean downloadUrlPic(String urlStr, File file) {        FileOutputStream fos = null;        InputStream is = null;        try {            URL url = new URL(urlStr);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            is = conn.getInputStream();            fos = new FileOutputStream(file);            byte[] buffer = new byte[1024];            int len = 0;            while ((len = is.read(buffer)) != -1) {                fos.write(buffer, 0, len);            }            fos.flush();            return true;        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                is.close();            } catch (IOException e) {                e.printStackTrace();            }            try {                fos.close();            } catch (IOException e) {                e.printStackTrace();            }        }        return false;    }    private String getFileMD5(String path) {        try {            MessageDigest digest = MessageDigest.getInstance("md5");            byte[] bytes = digest.digest(path.getBytes());            StringBuilder result = new StringBuilder();            String tempStr = null;            for (byte b : bytes) {                tempStr = Integer.toHexString(b & 0xff);                if (tempStr.length() == 1) {                    result.append("0");                }                result.append(tempStr);            }            return result.toString();        } catch (Exception e) {            e.printStackTrace();        }        return "";    }    private File getPicDiskCacheFile(Context context, String uniqueName) {        String cachePath;        if (Environment.MEDIA_MOUNTED.equals(Environment                .getExternalStorageState())) {            cachePath = context.getExternalCacheDir().getPath();        } else {            cachePath = context.getCacheDir().getPath();        }        return new File(cachePath + File.separator + uniqueName);    }    // 从网络获取用于显示在ImageView中的图片    private Bitmap loadUrlBitmap(String urlStr, ImageView imageView) {        InputStream is = null;        try {            URL url = new URL(urlStr);            HttpURLConnection conn = (HttpURLConnection) url.openConnection();            is = new BufferedInputStream(conn.getInputStream());            is.mark(is.available());                        Options options = new Options();            options.inJustDecodeBounds = true;            BitmapFactory.decodeStream(is, null, options);            ImageViewSize imageViewSize = getImageViewSize(imageView);            options.inSampleSize = getInSampleSize(imageViewSize, options);            options.inJustDecodeBounds = false;            is.reset();            Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);            conn.disconnect();            return bitmap;        } catch (Exception e) {            e.printStackTrace();        } finally {            try {                if (is != null) {                    is.close();                }            } catch (IOException e) {                e.printStackTrace();            }        }        return null;    }    private void sendMsgToUIHandler(final String path,            final ImageView imageView, Bitmap bitmap) {        ImageBeanHolder holder = new ImageBeanHolder();        holder.bitmap = bitmap;        holder.imageView = imageView;        holder.path = path;        Message message = Message.obtain();        message.obj = holder;        mUIHandler.sendMessage(message);    }    private void putBitmapToLruCache(String path, Bitmap bitmap) {        if (getBitmapFromLruCache(path) == null) {            if (bitmap != null) {                mLruCache.put(path, bitmap);            }        }    }    private Bitmap getBitmapFromLruCache(String path) {        return mLruCache.get(path);    }    private Bitmap decodeThumbnailFromResource(String path,            ImageViewSize imageViewSize) {        Options options = new Options();        // 不把位图加载到内存中,只获取位图的头文件信息        options.inJustDecodeBounds = true;        BitmapFactory.decodeFile(path, options);        int inSampleSize = getInSampleSize(imageViewSize, options);        options.inSampleSize = inSampleSize;        // 把位图解析到内存中        options.inJustDecodeBounds = false;        return BitmapFactory.decodeFile(path, options);    }    private int getInSampleSize(ImageViewSize imageViewSize, Options options) {        int imageViewWidth = imageViewSize.width;        int imageViewHeight = imageViewSize.height;        int picWidth = options.outWidth;        int picHeight = options.outHeight;        int inSampleSize = 1;        if (picWidth > imageViewWidth || picHeight > imageViewHeight) {            int widthScale = Math.round(picWidth * 1.0f / picHeight);            int heightScale = Math.round(picHeight * 1.0f / imageViewHeight);            inSampleSize = Math.max(widthScale, heightScale);        }        return inSampleSize;    }    private ImageViewSize getImageViewSize(ImageView imageView) {        ImageViewSize imageViewSize = new ImageViewSize();        DisplayMetrics metrics = imageView.getContext().getResources()                .getDisplayMetrics();        LayoutParams params = imageView.getLayoutParams();        int width = imageView.getWidth();// imageView的实际宽度        if (width <= 0) {            width = params.width;// layout中声明的宽度        }        if (width <= 0) {            width = imageView.getMaxWidth();// imageView的最大宽度        }        if (width <= 0) {            width = metrics.widthPixels;// 屏幕宽度        }        int height = imageView.getHeight();        if (height <= 0) {            height = params.height;        }        if (height <= 0) {            height = imageView.getMaxHeight();        }        if (height <= 0) {            height = metrics.heightPixels;        }        imageViewSize.width = width;        imageViewSize.height = height;        return imageViewSize;    }    private static class ImageBeanHolder {        Bitmap bitmap;        ImageView imageView;        String path;    }    private static class ImageViewSize {        int width;        int height;    }}


 

0 0
原创粉丝点击