思路:
从网络下载图片,通过AsyncTask开启线程,创建HttpURLConnection对象,把输入流转成Bitmap因为ListView图片错乱问题,需要给ImageView设置的Tag是图片的url链接,展示图片的时候,比较tag和url是否相等
代码:/** * 网络缓存工具类 */public class NetCacheUtils { PRivate static final String TAG = "NetCacheUtils"; public void getBitmapFromNet(ImageView imageView, String url) { //异步下载图片 new BitmapTask(imageView, url).execute(imageView, url); } class BitmapTask extends AsyncTask<Object, Void, Bitmap> { private ImageView imageView; private String url; public BitmapTask(ImageView imageView, String url) { this.imageView = imageView; this.url = url; this.imageView.setTag(this.url); } @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected Bitmap doInBackground(Object... params) { //使用url下载图片 Bitmap bitmap = download(url); return bitmap; } @Override protected void onPostExecute(Bitmap result) { //给ImageView设置图片 //由于ListView的重用机制, // 导致某个item有可能展示它所重用的那个item的图片,导致图片错乱 //解决方案:确保当前设置的图片和当前显示的imageView完全匹配 if (result != null) { String url = (String) imageView.getTag(); //判断当前下载的图片的url是否和ImageView的url一致,如果一致,说明完全匹配 if (this.url.equals(url)) { imageView.setImageBitmap(result); Log.i(TAG, "onPostExecute: 从网络上下载图片啦"); } } } } //下载图片 private Bitmap download(String url) { HttpURLConnection conn = null; try { conn = (HttpURLConnection) new URL(url).openConnection(); conn.setRequestMethod("GET"); conn.setConnectTimeout(6000);//设置连接超时 conn.setReadTimeout(6000);//设置读取超时 conn.connect();//连接 int responseCode = conn.getResponseCode();//获取返回码 if (responseCode == 200) { InputStream in = conn.getInputStream();//获取输入流 //使用输入流生成Bitmap对象 Bitmap bitmap = BitmapFactory.decodeStream(in); return bitmap; } } catch (Exception e) { e.printStackTrace(); }finally { if (conn != null) { conn.disconnect(); } } return null; }}思路:
创建本地缓存工具,首先创建缓存目录,图片url通过md5加密作为文件名从网络下载图片后,保存图片到本地展示图片时,首先根据url判断本地是否有缓存,如果有就读取本地缓存,没有就从网上下载代码: /** * 本地缓存工具类 */ public class LocalCacheUtils { //缓存文件夹 private String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + “/zhbj_cache/”;
//写缓存 public void setLocalCache(String url, Bitmap bitmap) { //将图片保存在本地文件中 File dir = new File(PATH); if (!dir.exists() || !dir.isDirectory()) { dir.mkdirs();//创建文件夹 } try { File cacheFile = new File(dir, MD5Encoder.encode(url)); //将图片压缩保存到本地,参数1:图片的格式,参数2:压缩比(0-100), 参数3:输出流 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(cacheFile)); } catch (Exception e) { e.printStackTrace(); } } //读缓存 public Bitmap getLocalCache(String url) { try { File cacheFile = new File(PATH, MD5Encoder.encode(url)); if (cacheFile.exists()) { //缓存存在 Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(cacheFile)); return bitmap; } } catch (Exception e) { e.printStackTrace(); } return null; } }思路:
创建HashMap,key是url,value是Bitmap从网络下载图片展示后,把bitmap存放到HashMap中,从本地缓存中读取图片展示后,把bitmap存放到HashMap中展示图片时,如果内存缓存有bitmap,则不需要从本地或者网络加载图片
代码: /** * 内存缓存 */ public class MemoryCacheUtils { private Map<String, Bitmap> mHashMap = new HashMap<>(); //写缓存 public void setMemoryCache(String url, Bitmap bitmap) { mHashMap.put(url, bitmap); } //读缓存 public Bitmap getMemroyCache(String url) { return mHashMap.get(url); } }思路: 1. 把bitmap用SoftReference包装起来,然后再存放到map集合中 2. 读取时先获取SoftReference对象,再从软引用对象中获取bitmap
获取虚拟机分配的最大内存,默认16M long maxMemory = Runtime.getRuntime().maxMemory(); maxSize,内存缓存上限 mLruCache = new LruCache<String, Bitmap>((int) (maxMemory/8)){ //返回单个对象占用内存的大小 @Override protected int sizeOf(String key, Bitmap value) { int byteCount = value.getRowBytes() * value.getHeight(); return byteCount; } };新闻热点
疑难解答