加载图片工具类
来源:互联网 发布:淘宝关键词提取工具 编辑:程序博客网 时间: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
- 加载图片工具类
- 图片加载工具类
- 加载图片工具类
- 图片加载工具类
- 图片加载工具类
- 加载图片的工具类
- 图片异步加载工具类
- 图片加载得工具类
- ImageLoader加载图片工具类
- Glide 图片加载工具类
- ImageLoaderUtil_图片加载工具类
- ImageLoader加载图片工具类
- 异步线程加载图片工具类
- Android LruCache图片异步加载工具类
- Android加载图片的工具类
- 异步加载图片的工具类
- ImageLoader加载本地图片的工具类
- 图片加载的缓存工具类
- 关于在项目中用到的动画效果(浅析)
- 计算机组成原理之指令调度和延迟分支
- 画网络拓扑图好用的工具
- springMVC + mybatis + bootstrap 框架学习
- 【Cubieboard2】配置编译内核支持SPI全双工通信驱动
- 加载图片工具类
- 最长递增子序列
- 误删Linux path中的路径恢复
- JS获取时间戳兼容问题
- javascript加载xml文件,兼容Chrome
- 同事们,开始逗闷子了。
- DirectX9中Pixel Coordinates System的一个怪异特性
- Windows下PostgreSQL安装图解
- Java实现斐波那契数列并输出前10000个数值