android 图片加载工具
来源:互联网 发布:java 获取根目录路径 编辑:程序博客网 时间:2024/05/22 16:56
实现思路:
根据指定的路径从内存中获取图片, 如果存在,则返回图片.
如果不存在,从硬盘中获取图片,如果存在,则返回图片,并且存入内存缓存中.
如果不存在,则从网络上获取图片,如果获取成功,现将图片二次压缩,
则将图片返回,并且存入到磁盘缓存中.
然后将整个的加载任务,添加到线程池中进行管理.
public class ImageLoader { private ImageLoader() { } private static ImageLoader instance; public static ImageLoader getInstance(Context ctx) { if (instance == null) { synchronized (ImageLoader.class) { if (instance == null) { instance = new ImageLoader(ctx); } } } return instance; } /** * 内存缓存 */ private LruCache<String, Bitmap> mMemoryCache; /** * 磁盘缓存 */ private DiskLruCache mDiskLruCache; private Context mContext; // 磁盘内存的大小 public static final long DISK_CACHE_SIZE = 1024 * 1024 * 50; // 10M public static final long IO_BUFFERED_SIZE = 1024 * 1024 * 8;// 8M public static final int DISK_CACHE_INDEX = 0; // 磁盘缓存是否创建成功 private boolean mIsDiskLruCacheCreated = false; public static final String TAG = "tag"; private static final ThreadFactory mThreadFactory = new ThreadFactory() { private final AtomicInteger mCount = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { // TODO 自动生成的方法存根 return new Thread(r, "ImageLoader#" + mCount.getAndIncrement()); } }; private static final int corePoolSize=Runtime.getRuntime().availableProcessors(); private static final int maximumPoolSize=corePoolSize*2+1; private static final int keepAliveTime=10; public static final Executor POOL_EXECUTOR = new ThreadPoolExecutor( corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>(),mThreadFactory); private HandlerThread handlerThread=new HandlerThread("handlerThread"); private Handler mHandler=new Handler(handlerThread.getLooper()){ public void handleMessage(android.os.Message msg) { ImageHolder holder= (ImageHolder) msg.obj; Bitmap bitmap=holder.bitmap; ImageView imageView=holder.imageView; String uri=(String) imageView.getTag(TAG_KEY_URI); if(uri.equals(holder.uri)){ imageView.setImageBitmap(bitmap); }else{ Log.v(TAG, "set image bitmap ,but url changed "); } }; }; public ImageLoader(Context ctx) { mContext = ctx.getApplicationContext(); // 内存中最大的容量 int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); int cacheSize = maxMemory / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } }; File diskCacheDir = getDiskCacheDir(mContext, "bitmap"); if (diskCacheDir.exists()) { diskCacheDir.mkdirs(); } try { if (getUsableSpace(diskCacheDir) > DISK_CACHE_SIZE) { mDiskLruCache = DiskLruCache.open(diskCacheDir, 1, 1, DISK_CACHE_SIZE); mIsDiskLruCacheCreated = true; } } catch (IOException e) { e.printStackTrace(); mIsDiskLruCacheCreated = false; } } public static final int TAG_KEY_URI=1; /** * 绑定图片与控件 外界调用的方法 * @param url * @param imageview * @param reqWidth * @param reqHeight */ public void bindBitmap(final String url,final ImageView imageview,final int reqWidth,final int reqHeight){ imageview.setTag(TAG_KEY_URI,url); Bitmap bitmap=loadBitmapFromMemCache(url); if(bitmap!=null){ imageview.setImageBitmap(bitmap); return; } Runnable loadTask=new Runnable() { @Override public void run() { Bitmap bitmap=loadBitmap(url,reqWidth,reqHeight); if(bitmap!=null){ ImageHolder holder=new ImageHolder(imageview, url, bitmap); Message msg=Message.obtain(); msg.obj=holder; mHandler.sendMessage(msg); } } }; POOL_EXECUTOR.execute(loadTask); } /** * 从内存中获取图片 * * @param key * @param bitmap */ public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) != null) { mMemoryCache.put(key, bitmap); } } public Bitmap loadBitmapFromMemCache(String url) { String key = hashKeyFromUrl(url); return getBitmapFromMemoryCache(key); } /** * 将图片存入到缓存 * * @param key * @return */ public Bitmap getBitmapFromMemoryCache(String key) { return mMemoryCache.get(key); } /** * 从内存缓存,磁盘缓存,网络上读取图片 * @param url * @param reqWidth * @param reqHeight * @return */ private Bitmap loadBitmap(String url, int reqWidth, int reqHeight) { Bitmap bitmap = loadBitmapFromMemCache(url); if (bitmap != null) { return bitmap; } bitmap = loadBitmapFromDiskCache(url, reqWidth, reqHeight); if (bitmap != null) { return bitmap; } bitmap = loadBitmapFromHttp(url, reqWidth, reqHeight); if (bitmap == null && !mIsDiskLruCacheCreated) { bitmap = loadBitmapFromUrl(url); } return bitmap; } /** * 从网络上获取图片,将下载的图片存入磁盘缓存中, 然后读取 * * @param url * @param reqWidth * @param reqHeight * @return */ private Bitmap loadBitmapFromHttp(String url, int reqWidth, int reqHeight) { if (Looper.getMainLooper() == Looper.myLooper()) { throw new RuntimeException(" 不再在主线程中访问网络"); } if (mDiskLruCache == null) { return null; } String key = hashKeyFromUrl(url); try { Editor editor = mDiskLruCache.edit(key); if (editor != null) { OutputStream os = editor.newOutputStream(DISK_CACHE_INDEX); if (downloadUrlToStream(url, os)) { editor.commit(); } else { editor.abort(); } mDiskLruCache.flush(); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } return loadBitmapFromDiskCache(url, reqWidth, reqHeight); } /** * 将指定网络路径的文件保存到指定的输入流中 * * @param url * @param os * @return */ public boolean downloadUrlToStream(String urlString, OutputStream os) { HttpURLConnection conn = null; BufferedInputStream bis = null; BufferedOutputStream bos = null; try { URL url = new URL(urlString); conn = (HttpURLConnection) url.openConnection(); bis = new BufferedInputStream(conn.getInputStream(), (int) IO_BUFFERED_SIZE); bos = new BufferedOutputStream(os); int len = 0; byte[] buff = new byte[20]; while ((len = bis.read(buff)) != -1) { bos.write(buff, 0, len); bos.flush(); } return true; } catch (Exception e) { e.printStackTrace(); } finally { if (conn != null) { conn.disconnect(); } if (bis != null) { try { bis.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } } return false; } /** * 从磁盘上获取图片 * * 从指定的磁盘路径中获取图片, 如果获取成功,将图片返回, 并且将图片存入内存缓存中 * * @param url * @param reqWidth * @param reqHeight * @return */ private Bitmap loadBitmapFromDiskCache(String url, int reqWidth, int reqHeight) { if (Looper.myLooper() == Looper.getMainLooper()) { Log.v(TAG, "load bitmap from UI thread . it's not recommended."); return null; } if (mDiskLruCache == null) { return null; } Bitmap bitmap = null; String key = hashKeyFromUrl(url); try { Snapshot snapshot = mDiskLruCache.get(key); if (snapshot != null) { FileInputStream fis = (FileInputStream) snapshot .getInputStream(DISK_CACHE_INDEX); FileDescriptor fds = fis.getFD(); bitmap = BitmapUtils.decodeBitmapFromFileDescriptor(fds, reqWidth, reqHeight); if (bitmap != null) { addBitmapToMemoryCache(url, bitmap); } } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } return bitmap; } /** * 从网络上下载图片 * * @param urlString * @return */ private Bitmap loadBitmapFromUrl(String urlString) { Bitmap bitmap = null; HttpURLConnection conn = null; BufferedInputStream bis = null; try { URL url = new URL(urlString); conn = (HttpURLConnection) url.openConnection(); bis = new BufferedInputStream(conn.getInputStream(), (int) IO_BUFFERED_SIZE); bitmap = BitmapFactory.decodeStream(bis); } catch (Exception e) { } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } if (conn != null) { conn.disconnect(); conn = null; } } return bitmap; } /** * 将网络路径加密 * * @param url * @return */ private String hashKeyFromUrl(String url) { String result = null; try { MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(url.getBytes()); result = byteToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) { result = String.valueOf(url.hashCode()); } return result; } private String byteToHexString(byte[] bytes) { StringBuffer sb = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xff & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } /** * 指定磁盘的文件目录 * * @param ctx * @param uniqueName * @return */ @SuppressLint("NewApi") public File getDiskCacheDir(Context ctx, String uniqueName) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageDirectory()) || !Environment.isExternalStorageRemovable()) { cachePath = ctx.getExternalCacheDir().getPath(); } else { cachePath = ctx.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); } /** * 获取指定目录的大小 * * @param path * @return */ @SuppressLint("NewApi") private long getUsableSpace(File path) { if (Build.VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD) { return path.getUsableSpace(); } StatFs stats = new StatFs(path.getPath()); return stats.getBlockSize() * stats.getAvailableBlocks(); } private class ImageHolder { public ImageView imageView; public String uri; public Bitmap bitmap; public ImageHolder(ImageView imageView, String uri, Bitmap bitmap) { this.imageView = imageView; this.uri = uri; this.bitmap = bitmap; } }}
0 0
- android 图片加载工具
- Android LruCache图片异步加载工具类
- Android加载图片的工具类
- Android开发之图片加载工具Picasso
- 加载图片工具类
- 图片加载工具类
- Fresco图片加载工具
- 加载图片工具类
- 图片加载工具类
- Glide图片加载工具
- 图片加载工具类
- android ImageLoader加载本地图片的工具类(使用方法)
- android ImageLoader加载本地图片的工具类
- android ImageLoader加载本地图片的工具类
- android ImageLoader加载本地图片的工具类
- android ImageLoader加载本地图片的工具类
- android ImageLoader加载本地图片的工具类
- android ImageLoader加载本地图片的工具类
- 联想G50笔记本如何安装系统
- android的五种布局模式
- HDU 2444 The Accomodation of Students(二分图判定+最大匹配)
- 天声人語 20160213 アインシュタインの宿題
- 03环信好友管理 - 监听"加好友"的请求
- android 图片加载工具
- 单片机C语言 串口传输 结构体
- opencv 下载地址
- 日经春秋 20160213
- C语言memset详解
- LVS NAT 模式
- JAVA容器类
- 阶乘
- 格式化数据#7:开放课/公开课