| 
 升级    24%  精华0帖子198e币997 元
 | 
| 以前发过一篇有关加载图片的文章,是处理应用中常常遇到的加载列表缩略图与大图的文章,当时是因为赶项目,时间仓促,并没有过多的考虑,闲暇时间,反思了一下,觉得以前所用的方法过于笨拙且消耗手机资源加大,思量再三,又重新做了一个 此次引用了线程池ExecutorService与改用了Handler的post方法
 
 采用线程池的目的:
 1、大幅减少开启线程的数量,重复利用有限的线程
 2、减少手机的资源损耗
 
 采用Handler的Post方法的目的:
 1、是为了更加规范的调用API
 2、是图片的呈现更加可靠
 
 <ignore_js_op>
   
 不多说了!
 
 -------------------------------------------------------------------------------------------------------------------------------
 java代码:
 
 图片加载管理类AsynDownloadManager,需要从外部传入UI线程的Handler
 
 
 public class AsynDownloadManager {
 private static String ThumbFolder = "Temp/Thumb";//缩略图文件夹
 private static String ImageFolder="Temp/Image";//大图文件夹
 
 private static Handler handler;//UI handler
 private static ExecutorService pool;//线程池
 private static Map<String, SoftReference<Bitmap>> cacheImage;//软引用
 private int ThreadCount=5;//默认线程池可用线程数
 
 /**
 * 创建目录
 */
 static {
 if (isSDCardAvailable()) {
 File file = new File(Environment.getExternalStorageDirectory(),ThumbFolder);
 if (!file.exists()) {
 file.mkdirs();
 }
 File file1 = new File(Environment.getExternalStorageDirectory(),ImageFolder);
 if (!file1.exists()) {
 file1.mkdirs();
 }
 }
 }
 
 public AsynDownloadManager() {
 cacheImage = new HashMap<String, SoftReference<Bitmap>>();
 pool = Executors.newFixedThreadPool(ThreadCount);
 }
 
 static AsynDownloadManager manager=null;
 
 
 
 //**********************************************************************************供外部调用的主方法
 /**
 * 获取加载器
 * @return AsynDownloadManager
 */
 public static AsynDownloadManager getInterface(){
 if(manager==null){
 manager=new AsynDownloadManager();
 }
 return manager;
 }
 /**
 * 加载图片(缩略图)
 * @param url
 * @param imageView
 */
 public static void loadThembBitmap(final String url, final ImageView imageView) {
 pool.submit(new Runnable() {
 public void run() {
 //首先从SoftReference中获取
 Bitmap bitmapTemp=getFromSoftReference(url);
 if(bitmapTemp==null){
 //从SDcard中获取
 bitmapTemp=getFromSDcard(url, ThumbFolder,false);
 if(bitmapTemp==null){
 //从URL获取
 bitmapTemp=getFromURL(url, ThumbFolder,false);
 }
 }
 final Bitmap bitmap=bitmapTemp;
 handler.post(new Runnable() {//发送到Handler队列,依次显示
 public void run() {
 imageView.setImageBitmap(bitmap);
 }
 });
 }
 });
 }
 
 /**
 * 加载图片(大图)
 * @param url
 * @param imageView
 * @param isZip 是否压缩
 */
 public static void  loadBitmap(final String url, final ImageView imageView,final boolean isZip){
 pool.submit(new Runnable() {
 public void run() {
 //因为单图较大,不用SoftReference
 
 Bitmap bitmapTemp=null;
 //从SDcard中获取
 bitmapTemp=getFromSDcard(url, ImageFolder,isZip);
 if(bitmapTemp==null){
 //从URL获取
 bitmapTemp=getFromURL(url, ImageFolder,isZip);
 }
 final Bitmap bitmap=bitmapTemp;
 handler.post(new Runnable() {//发送到Handler队列,依次显示
 public void run() {
 imageView.setImageBitmap(bitmap);
 }
 });
 }
 });
 }
 //**********************************************************************************
 
 
 
 
 
 
 
 /**
 * 从缓存中获取
 * @param url
 * @param bitmap
 * @return Bitmap
 */
 public static Bitmap getFromSoftReference(String url){
 if(!cacheImage.containsKey(url)){
 return null;
 }else{
 return cacheImage.get(url).get();
 }
 }
 
 /**
 * 从SDcard获取(下载并返回)
 * @param imageUrl
 * @param folderPath
 * @return Bitmap
 */
 public static Bitmap getFromURL(String imageUrl, String folderPath,boolean isZip){
 URL mUrl;
 InputStream is = null;
 Bitmap bitmap = null;
 try {
 mUrl = new URL(imageUrl);
 is = (InputStream) mUrl.getContent();
 if(isSDCardAvailable()){
 String fileName = imageUrl.substring(imageUrl.lastIndexOf('/')+1);
 File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
 File file = new File(basePathFile, fileName+".tmp");
 if(!file.exists()){
 file.createNewFile();
 }
 FileOutputStream outputStream = new FileOutputStream(file);
 byte[] b = new byte[512];
 int offset;
 while((offset=is.read(b))!=-1){
 outputStream.write(b, 0, offset);
 }
 outputStream.flush();
 outputStream.close();
 is.close();
 basePathFile = new File(basePathFile, fileName);
 if(basePathFile.exists()){
 basePathFile.delete();
 }
 if(file.renameTo(basePathFile)){
 is = new FileInputStream(basePathFile);
 }
 // 读取图片
 bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
 
 if(isZip==false){
 //缩略图加入到软引用
 SoftReference<Bitmap> softReference=new SoftReference<Bitmap>(bitmap);
 cacheImage.put(imageUrl, softReference);
 }
 
 }
 } catch (Exception e) {
 e.printStackTrace();
 return null;
 }
 
 return bitmap;
 }
 
 /**
 * 从SDcard获取
 * @param url
 * @param folderPath
 * @return Bitmap
 */
 public static Bitmap getFromSDcard(String url,String folderPath,boolean isZip){
 Bitmap bitmap = null;
 String fileName = url.substring(url.lastIndexOf('/')+1);
 File basePathFile = new File(Environment.getExternalStorageDirectory(), folderPath);
 basePathFile = new File(basePathFile, fileName);
 if(basePathFile.exists()){
 bitmap=getBitmap(basePathFile.getAbsolutePath(), isZip);
 }
 return bitmap;
 }
 /**
 * 检查SDCard是否可用
 *
 * @return
 */
 public static final boolean isSDCardAvailable() {
 return Environment.getExternalStorageState().equals(
 Environment.MEDIA_MOUNTED);
 }
 
 //---------------------------------------------------------------------------------
 
 /**
 * 读取SDcard中的图片资源(解决内存溢出问题)
 * @param pathName 文件路径名
 * @param isZip  是否降低采样率
 * @return Bitmap
 */
 public static Bitmap getBitmap(String pathName,boolean isZip){
 Bitmap bitmap=null;
 if(isZip==true){
 BitmapFactory.Options options = new BitmapFactory.Options();
 options.inSampleSize = 2;//图片宽高都为原来的二分之一,即图片为原来的四分之一
 bitmap=BitmapFactory.decodeFile(pathName, options);
 }else{
 bitmap=BitmapFactory.decodeFile(pathName);
 }
 return  bitmap;
 }
 
 //---------------------------------------------------------------便于外部修改参数
 public static String getThumbFolder() {
 return ThumbFolder;
 }
 
 public static void setThumbFolder(String thumbFolder) {
 ThumbFolder = thumbFolder;
 }
 
 public static String getImageFolder() {
 return ImageFolder;
 }
 
 public static void setImageFolder(String imageFolder) {
 ImageFolder = imageFolder;
 }
 
 public int getThreadCount() {
 return ThreadCount;
 }
 
 public void setThreadCount(int threadCount) {
 ThreadCount = threadCount;
 }
 
 public Handler getHandler() {
 return handler;
 }
 
 public void setHandler(Handler handler) {
 this.handler = handler;
 }
 
 
 
 }
 
 
 
 ------------------------------------------------------------------------------------------------------------------------------
 调用示例:
 
 一、对于缩略图:
 1、在Activity中实例化AsynDownloadManager:
 Handler handler=new Handler();
 
 
 2、对于ListView或GridView中的缩略图,一般可在自定义Adapter的的构造中:
 AsynDownloadManager manager=AsynDownloadManager.getInterface();
 manager.setHandler(handler);
 
 getView()方法中作如下调用:
 manager.loadThembBitmap(urlList.get(position), imageView);
 
 3、OK
 
 二、对于大图:(压缩)
 
 前两步同上
 
 3、 直接调用
 AsynDownloadManager.getInterface().loadBitmap(url, ImageView, true);
 当然最后那个参数也可以用false,即不压缩的模式
 
 ---------------------------------------------------------------------------------------------------------------------------------
 
 OK!
 |  |