android 新闻图片加载,缓存处理
来源:互联网 发布:ubuntu tar 解压命令 编辑:程序博客网 时间:2024/05/22 09:00
在开发中,遇到很多大量图片呈现给用户,那么我们怎么又快又高效的显示给用户呢?
在这里结合前人写的文章和自己的一些改动。
一般我们写的过程中是这么处理的:先去缓存(WeakHashMap<String, Bitmap>来存储图片)中提取,这样速度快又节约流量,缓存中没有再选择本地有图片没有,如果两者都没有则只有从网络去获取。
我们先分开讲解
方法一:网络下载
方法二:从本地文件加载
方法三:从缓存中读取
先来说方法一:
加载很多图片的时候,我们经常用多线程在后台下载,在handler中将图片呈现在界面。
直接上代码
//网络获取图片 protected Bitmap getNetBitmapByURL(String urlString) {URL url = null;InputStream inputStream = null;HttpURLConnection urlConnection = null;Bitmap bmp = null;try {url = new URL(urlString);urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("GET");urlConnection.setConnectTimeout(10000);inputStream = urlConnection.getInputStream();byte[] bt = getBytesFromStream(inputStream);bmp = BitmapFactory.decodeByteArray(bt, 0, bt.length);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (null != inputStream) {try {inputStream.close();inputStream = null;} catch (IOException e) {e.printStackTrace();}}if (null != urlConnection) {urlConnection.disconnect();urlConnection = null;}}return bmp;}// 数据流private byte[] getBytesFromStream(InputStream inputStream) {ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[1024];int len = 0;while (len != -1) {try {len = inputStream.read(b);} catch (IOException e) {e.printStackTrace();}if (len != -1) {baos.write(b, 0, len); }}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return baos.toByteArray();}这个地方获取了Bitmap 用handler呈现就很好搞定
再来说方法二本地获取:
直接根据图片路径获取Bitmap
private boolean cacheBmpToMemory(File file) {boolean sucessed = true;InputStream inputStream = null;try {inputStream = new FileInputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();sucessed = false;}byte[] bs = getBytesFromStream(inputStream);Bitmap bitmap = BitmapFactory.decodeByteArray(bs, 0, bs.length);if (bitmap == null) {return null;}return bitmap;}private byte[] getBytesFromStream(InputStream inputStream) {boolean b2 = true;ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[1024];int len = 0;while (len != -1 && b2) {try {len = inputStream.read(b);if (len != -1) {baos.write(b, 0, len);}} catch (IOException e) {b2 = false;try {inputStream.close();} catch (IOException e1) {}}}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return baos.toByteArray();}
方法三缓存获取:
用弱引用:WeakHashMap<String, Bitmap>,以弱键 实现的基于哈希表的 Map,在 WeakHashMap 中,当某个键不再正常使用时,将自动移除其条目。更精确地说,对于一个给定的键,其映射的存在并不阻止垃圾回收器对该键的丢弃,这就使该键成为可终止的,被终止,然后被回收。丢弃某个键时,其条目从映射中有效地移除。
WeakHashMap 中的每个键对象间接地存储为一个弱引用的指示对象。因此,不管是在映射内还是在映射之外,只有在垃圾回收器清除某个键的弱引用之后,该键才会自动移除
这个地方结合方法一和方法二,写了一个有关图片缓存的解决方法。
java文件:
ImageCache.java
package com.imageService;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.util.WeakHashMap;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Bitmap.CompressFormat;import android.os.Environment;public class ImageCache extends WeakHashMap<String, Bitmap> {private static ImageCache mNetImageViewCache = new ImageCache();private static final String CACHE_FILE = "/Cache";private ImageCache() {}public static ImageCache getInstance() {return mNetImageViewCache;}/** * 判断图片是否存在首先判断内存中是否存在然后判断本地是否存在 * * @param url * @return */public boolean isBitmapExit(String url) {boolean isExit = containsKey(url);if (false == isExit) {isExit = isLocalHasBmp(url);}return isExit;}/* * 判断本地有没有 */private boolean isLocalHasBmp(String url) {boolean isExit = true;String name = changeUrlToName(url);String filePath = isCacheFileIsExit();File file = new File(filePath, name);if (file.exists()) {isExit = cacheBmpToMemory(file, url);} else {isExit = false;}return isExit;}/* * 将本地图片缓存到内存中 */private boolean cacheBmpToMemory(File file, String url) {boolean sucessed = true;InputStream inputStream = null;try {inputStream = new FileInputStream(file);} catch (FileNotFoundException e) {e.printStackTrace();sucessed = false;}byte[] bs = getBytesFromStream(inputStream);Bitmap bitmap = BitmapFactory.decodeByteArray(bs, 0, bs.length);if (bitmap == null) {return false;}this.put(url, bitmap, false);return sucessed;}private byte[] getBytesFromStream(InputStream inputStream) {boolean b2 = true;ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[1024];int len = 0;while (len != -1 && b2) {try {len = inputStream.read(b);if (len != -1) {baos.write(b, 0, len);}} catch (IOException e) {b2 = false;try {inputStream.close();} catch (IOException e1) {}}}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return baos.toByteArray();}/* * 判断缓存文件夹是否存在如果存在怎返回文件夹路径,如果不存在新建文件夹并返回文件夹路径 */private String isCacheFileIsExit() {String filePath = "";String rootpath = "";if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {rootpath = Environment.getExternalStorageDirectory().toString();}filePath = rootpath + CACHE_FILE;File file = new File(filePath);if (!file.exists()) {file.mkdirs();}return filePath;}/* * 将url变成图片的地址 */private String changeUrlToName(String url) {String name = url.replaceAll(":", "_");name = name.replaceAll("//", "_");name = name.replaceAll("/", "_");name = name.replaceAll("=", "_");name = name.replaceAll(",", "_");name = name.replaceAll("&", "_");return name;}public Bitmap put(String key, Bitmap value) {String filePath = isCacheFileIsExit();String name = changeUrlToName(key);File file = new File(filePath, name);OutputStream outputStream = null;try {outputStream = new FileOutputStream(file);value.compress(CompressFormat.JPEG, 100, outputStream);} catch (FileNotFoundException e) {e.printStackTrace();}try {if (null != outputStream)outputStream.flush();} catch (IOException e1) {e1.printStackTrace();}try {if (null != outputStream)outputStream.flush();} catch (IOException e) {e.printStackTrace();}if (null != outputStream) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}outputStream = null;}return super.put(key, value);}/** * * @param key * @param value * @param isCacheToLocal * 是否缓存到本地 * @return */public Bitmap put(String key, Bitmap value, boolean isCacheToLocal) {if (isCacheToLocal) {return this.put(key, value);} else {return super.put(key, value);}}}
ImageService.java
package com.imageService;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.lang.ref.SoftReference;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.Handler;import android.os.Message;import android.util.Log;import android.widget.ImageView;/** * @author jingche.yhq 使用说明:1.先增加权限: <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 2.图片URL和ImageView直接输入函数 EX: ImageService imageService = new ImageService(this); ImageView imageView; imageService.setBitmapByURL2("http://i1.itc.cn/20120801/a75_b0e447db_3573_ab5c_2058_5845d13545b9_1.jpg", imageView,defaultBitmap); */public class ImageService {//*********************************************线程池获取图片资源******************************************************//本地数据缓存public Map<String, SoftReference<Bitmap>> imageCacheMap = new HashMap<String, SoftReference<Bitmap>>();//固定五个线程来执行任务 private ExecutorService executorService = Executors.newFixedThreadPool(5); //回调函数使用 final static ImageService imageService = new ImageService(); public static ImageService getInstance(){return imageService;}/** * 将图片放进缓存,图片名称是由URL去掉一些符号得到 * * @param url * 地址 * @param bitmap * 图片 */public void putImageCache(String url, Bitmap bitmap) {try {if(!ImageCache.getInstance().isBitmapExit(url));ImageCache.getInstance().put(url, bitmap, true);} catch (Exception e) {e.printStackTrace();}}/** * * @param url图片URL * * @param imageView imageView * * @param defaultBitmap 获取图片失败这显示默认图片 */public void setBitmapByURL(String url,final ImageView imageView,final Bitmap defaultBitmap,boolean isCacheToLocal) {//采用Handler+Thread+封装外部接口 //如果缓存过就会从缓存中取出图像,ImageCallback接口中方法也不会被执行Bitmap cacheImage = loadBitmap(url,imageView,isCacheToLocal,new ImageCallback() { //请参见实现:如果第一次加载URL时下面方法会执行@Overridepublic void imageLoad(ImageView imageView, Bitmap bitmap) {//如果返回的Bitmap为空这选择默认图片 if (bitmap!=null) { imageView.setImageBitmap(bitmap); }else { imageView.setImageBitmap(defaultBitmap); }} }); if(cacheImage!=null){ imageView.setImageBitmap(cacheImage); }else { // imageView.setImageBitmap(defaultBitmap);}} /** * * @param imageUrl 图像URL地址 * @param imageCallback 回调接口 * @return 返回内存中缓存的图像,第一次加载返回null */ public Bitmap loadBitmap(final String imageUrl,final ImageView imageView,final boolean isCacheToLocal,final ImageCallback imageCallback) { //如果缓存过就从缓存中取出数据 final Handler handler = new Handler() { @Override public void handleMessage(Message msg) { imageCallback.imageLoad(imageView, (Bitmap)msg.obj); } }; if (imageCacheMap.containsKey(imageUrl)) { Log.e("提示", "缓存获取图片"); SoftReference<Bitmap> softReference = imageCacheMap.get(imageUrl); if (softReference.get() != null) { return softReference.get(); } }else if(ImageCache.getInstance().isBitmapExit(imageUrl)){ Log.e("提示", "本地获取图片"); Bitmap bitmap=null; try {bitmap = ImageCache.getInstance().get(imageUrl);} catch (Exception e) {bitmap = null;}return bitmap; } else { //缓存中没有图像,则从网络上取出数据,并将取出的数据缓存到内存中 executorService.submit(new Runnable() { public void run() { try { //获取图片 final Bitmap bitmap = getNetBitmapByURL(imageUrl); //将图片放置到内存中 Log.e("提示", "网络获取图片"+Thread.currentThread().getName()); if(bitmap!=null){ Log.e("提示", "存储图"); imageCacheMap.put(imageUrl, new SoftReference<Bitmap>(bitmap)); ImageCache.getInstance().put(imageUrl, bitmap, isCacheToLocal); } Message msg = handler.obtainMessage(0, bitmap); handler.sendMessage(msg); } catch (Exception e) { throw new RuntimeException(e); } } }); } return null; } //网络获取图片 protected Bitmap getNetBitmapByURL(String urlString) {URL url = null;InputStream inputStream = null;HttpURLConnection urlConnection = null;Bitmap bmp = null;try {url = new URL(urlString);urlConnection = (HttpURLConnection) url.openConnection();urlConnection.setRequestMethod("GET");urlConnection.setConnectTimeout(10000);inputStream = urlConnection.getInputStream();byte[] bt = getBytesFromStream(inputStream);bmp = BitmapFactory.decodeByteArray(bt, 0, bt.length);} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (null != inputStream) {try {inputStream.close();inputStream = null;} catch (IOException e) {e.printStackTrace();}}if (null != urlConnection) {urlConnection.disconnect();urlConnection = null;}}return bmp;}// 数据流private byte[] getBytesFromStream(InputStream inputStream) {ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] b = new byte[1024];int len = 0;while (len != -1) {try {len = inputStream.read(b);} catch (IOException e) {e.printStackTrace();}if (len != -1) {baos.write(b, 0, len); }}if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}return baos.toByteArray();} //对外界开放的回调接口 private interface ImageCallback { //注意 此方法是用来设置目标对象的图像资源 public void imageLoad(ImageView imageView, Bitmap bitmap); } }
test
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageService imageService = new ImageService(); ImageView imageView = (ImageView)findViewById(R.id.imageView1); imageService.setBitmapByURL("http://i1.itc.cn/20120801/a75_b0e447db_3573_ab5c_2058_5845d13545b9_1.jpg", imageView,BitmapFactory.decodeResource(getResources(), R.drawable.icon)); }
呵呵!很多不足,欢迎拍砖哈。
- android 新闻图片加载,缓存处理
- Android 加载大量图片的三级缓存处理
- Android网络图片加载缓存处理库的使用
- Android网络图片加载缓存处理库的使用
- Android网络图片加载缓存处理库的使用
- Android网络图片加载缓存处理库的使用
- Android--图片加载处理(内存溢出和三级缓存)
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android 图片缓存处理
- Android图片缓存处理
- Android 图片缓存处理
- 网络加载图片及图片缓存处理
- JS键盘监听事件的键盘码
- 根据图的度数判断图的连通性的Havel-Hakimi定理
- Python抓取中文网页
- mac 地址限制 DHCPD 配置
- Spring原理
- android 新闻图片加载,缓存处理
- 汉字在url上面的传递
- winform程序使textbox获得输入焦点
- Android代码片段
- C#操作读取excel数据
- 关于div居中的话题
- 单例模式
- android-apktool 中文使用说明
- Android事件侦听器回调方法浅谈