实现二级缓存加载图片的功能,在使用DiskLruCache时,需先在工程中添加名为libcore.io的包,并将DiskLruCache.Java文件放进去。DiskLruCache直接百度下载即可。
在GridView的适配器中,为ImageView添加图片时,先从内存缓存中加载,内存中无缓存的话则在磁盘缓存中加载,磁盘缓存也没有的话开启线程下载,然后将下载的图片缓存到磁盘,内存中。下载的图片最好先进行压缩,文章最后给出了压缩代码,但本例中并未实现压缩。
public class ErJiHuanCun extends ArrayAdapter<String> { private Set<BitmapWorkerTask> taskCollection; private LruCache<String, Bitmap> mMemoryCache; private DiskLruCache mDiskLruCache; private GridView mPhotoWall; private int mItemHeight = 0; public ErJiHuanCun(Context context, int textViewResourceId, String[] objects, GridView photoWall) { super(context, textViewResourceId, objects); mPhotoWall = photoWall; taskCollection = new HashSet<BitmapWorkerTask>(); // 获取应用程序最大可用内存 int maxMemory = (int) Runtime.getRuntime().maxMemory(); int cacheSize = maxMemory / 8; // 设置图片缓存大小为程序最大可用内存的1/8 mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; try { // 获取图片缓存路径 File cacheDir = getDiskCacheDir(context, "thumb"); if (!cacheDir.exists()) { cacheDir.mkdirs(); } // 创建DiskLruCache实例,初始化缓存数据 mDiskLruCache = DiskLruCache .open(cacheDir, getAppVersion(context), 1, 10 * 1024 * 1024); } catch (IOException e) { e.printStackTrace(); } } @Override public View getView(int position, View convertView, ViewGroup parent) { final String url = getItem(position); View view; if (convertView == null) { view = LayoutInflater.from(getContext()).inflate(R.layout.photo_layout, null); } else { view = convertView; } final ImageView imageView = (ImageView) view.findViewById(R.id.photo); if (imageView.getLayoutParams().height != mItemHeight) { imageView.getLayoutParams().height = mItemHeight; } // 给ImageView设置一个Tag,保证异步加载图片时不会乱序 imageView.setTag(url); imageView.setImageResource(R.drawable.ic_launcher); loadBitmaps(imageView, url); return view; } public void addBitmapToMemoryCache(String key, Bitmap bitmap) { if (getBitmapFromMemoryCache(key) == null) { mMemoryCache.put(key, bitmap); } } public Bitmap getBitmapFromMemoryCache(String key) { return mMemoryCache.get(key); } public void loadBitmaps(ImageView imageView, String imageUrl) { try { Bitmap bitmap = getBitmapFromMemoryCache(imageUrl); if (bitmap == null) { BitmapWorkerTask task = new BitmapWorkerTask(); taskCollection.add(task); task.execute(imageUrl); } else { if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } } } catch (Exception e) { e.printStackTrace(); } } public void cancelAllTasks() { if (taskCollection != null) { for (BitmapWorkerTask task : taskCollection) { task.cancel(false); } } } public File getDiskCacheDir(Context context, String uniqueName) { String cachePath; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) { cachePath = context.getExternalCacheDir().getPath(); } else { cachePath = context.getCacheDir().getPath(); } return new File(cachePath + File.separator + uniqueName); } public int getAppVersion(Context context) { try { PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); return info.versionCode; } catch (NameNotFoundException e) { e.printStackTrace(); } return 1; } public void setItemHeight(int height) { if (height == mItemHeight) { return; } mItemHeight = height; notifyDataSetChanged(); } public String hashKeyForDisk(String key) { String cacheKey; try { final MessageDigest mDigest = MessageDigest.getInstance("MD5"); mDigest.update(key.getBytes()); cacheKey = bytesToHexString(mDigest.digest()); } catch (NoSuchAlgorithmException e) { cacheKey = String.valueOf(key.hashCode()); } return cacheKey; } public void flushCache() { if (mDiskLruCache != null) { try { mDiskLruCache.flush(); } catch (IOException e) { e.printStackTrace(); } } } private String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); 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(); } class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { private String imageUrl; @Override protected Bitmap doInBackground(String... params) { imageUrl = params[0]; FileDescriptor fileDescriptor = null; FileInputStream fileInputStream = null; Snapshot snapShot = null; try { // 生成图片URL对应的key final String key = hashKeyForDisk(imageUrl); // 查找key对应的缓存 snapShot = mDiskLruCache.get(key); if (snapShot == null) { // 如果没有找到对应的缓存,则准备从网络上请求数据,并写入缓存 DiskLruCache.Editor editor = mDiskLruCache.edit(key); if (editor != null) { OutputStream outputStream = editor.newOutputStream(0); if (downloadUrlToStream(imageUrl, outputStream)) { editor.commit(); } else { editor.abort(); } } // 缓存被写入后,再次查找key对应的缓存 snapShot = mDiskLruCache.get(key); } if (snapShot != null) { fileInputStream = (FileInputStream) snapShot.getInputStream(0); fileDescriptor = fileInputStream.getFD(); } // 将缓存数据解析成Bitmap对象 Bitmap bitmap = null; if (fileDescriptor != null) { // bitmap = BitmapFactory.decodeFileDescriptor(fileDescriptor); WindowManager wm= (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE); int width=wm.getDefaultDisplay().getWidth(); bitmap= ImageResizer.decodeSampleBithmapFromFileDescriptor(fileDescriptor,width/3,width/3); } if (bitmap != null) { // 将Bitmap对象添加到内存缓存当中 addBitmapToMemoryCache(params[0], bitmap); } return bitmap; } catch (IOException e) { e.printStackTrace(); } finally { if (fileDescriptor == null && fileInputStream != null) { try { fileInputStream.close(); } catch (IOException e) { } } } return null; } @Override protected void onPostExecute(Bitmap bitmap) { super.onPostExecute(bitmap); // 根据Tag找到相应的ImageView控件,将下载好的图片显示出来。 ImageView imageView = (ImageView) mPhotoWall.findViewWithTag(imageUrl); if (imageView != null && bitmap != null) { imageView.setImageBitmap(bitmap); } taskCollection.remove(this); } private boolean downloadUrlToStream(String urlString, OutputStream outputStream) { HttpURLConnection urlConnection = null; BufferedOutputStream out = null; BufferedInputStream in = null; try { final URL url = new URL(urlString); urlConnection = (HttpURLConnection) url.openConnection(); in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024); out = new BufferedOutputStream(outputStream, 8 * 1024); int b; while ((b = in.read()) != -1) { out.write(b); } return true; } catch (final IOException e) { e.printStackTrace(); } finally { if (urlConnection != null) { urlConnection.disconnect(); } try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (final IOException e) { e.printStackTrace(); } } return false; } }}
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
软考中级精品资料免费领
- 历年真题答案解析
- 备考技巧名师总结
- 高频考点精准押题
- 资料下载
- 历年真题
193.9 KB下载数265
191.63 KB下载数245
143.91 KB下载数1142
183.71 KB下载数642
644.84 KB下载数2755
相关文章
发现更多好内容猜你喜欢
AI推送时光机Android二级缓存加载图片实现照片墙功能
后端开发2023-05-31
Android中Glide加载图片并实现图片缓存
后端开发2022-06-06
Android实现图片缓存与异步加载
后端开发2022-06-06
Android实现从缓存中读取图片与异步加载功能类
后端开发2022-06-06
Android实现图片异步加载及本地缓存
后端开发2022-06-06
Android实现图片异步请求加三级缓存
后端开发2022-06-06
Android实现拍照、选择图片并裁剪图片功能
后端开发2022-06-06
Android中使用二级缓存、异步加载批量加载图片完整案例
后端开发2022-06-06
Android实现图片异步加载并缓存到本地
后端开发2022-06-06
android异步加载图片并缓存到本地实现方法
后端开发2022-06-06
Android使用缓存机制实现文件下载及异步请求图片加三级缓存
后端开发2022-06-06
Android图片三级缓存的原理及其实现
后端开发2023-05-30
Android实现图片预览与保存功能
后端开发2024-04-02
javascript如何实现图片预加载和懒加载功能
后端开发2023-06-14
Android实现拍照、选择相册图片并裁剪功能
后端开发2022-06-06
Kotlin实现网络图片下载和保存功能
后端开发2023-02-07
Android 实现WebView点击图片查看大图列表及图片保存功能
后端开发2022-06-06
JS如何实现图片预加载之无序预加载功能
后端开发2024-04-02
Android怎么实现图片预览与保存功能
后端开发2023-06-30
android保存图片到相册功能怎么实现
后端开发2024-04-02
咦!没有更多了?去看看其它编程学习网 内容吧