分享

Android异步加载网络图片

 hncdman 2022-05-09 发布于湖南省

置顶linghu_java于 2013-01-28 11:19:58 发布1563 收藏 1

分类专栏: Android开发

Android图片的异步加载,主要原理:

加载图片时先查看缓存中时候存在该图片,如果存在则返回该图片,否则先加载载一个默认的占位图片,同时创建一个通过网络获取图片的任务并添加,任务完成后放松消息给主线程更新界面。

使用方法:

[java]  view plain copy
  1. AsynImageLoader asynImageLoader = new AsynImageLoader();  

  2. asynImageLoader.showImageAsyn(imageView, imageUrl, resId);  

类代码:

[java]  view plain copy
  1. package com.wangge.uumao.http;  

  2. import java.lang.ref.SoftReference;  

  3. import java.util.ArrayList;  

  4. import java.util.HashMap;  

  5. import java.util.List;  

  6. import java.util.Map;  

  7. import android.graphics.Bitmap;  

  8. import android.os.Handler;  

  9. import android.os.Message;  

  10. import android.util.Log;  

  11. import android.widget.ImageView;  

  12. import com.wangge.uumao.util.PicUtil;  

  13. public class AsynImageLoader {  

  14.     private static final String TAG = "AsynImageLoader";  

  15.     // 缓存下载过的图片的Map  

  16.     private Map<String, SoftReference<Bitmap>> caches;  

  17.     // 任务队列  

  18.     private List<Task> taskQueue;  

  19.     private boolean isRunning = false;  

  20.     public AsynImageLoader(){  

  21.         // 初始化变量  

  22.         caches = new HashMap<String, SoftReference<Bitmap>>();  

  23.         taskQueue = new ArrayList<AsynImageLoader.Task>();  

  24.         // 启动图片下载线程  

  25.         isRunning = true;  

  26.         new Thread(runnable).start();  

  27.     }  

  28.     /** 

  29.      *  

  30.      * @param imageView 需要延迟加载图片的对象 

  31.      * @param url 图片的URL地址 

  32.      * @param resId 图片加载过程中显示的图片资源 

  33.      */  

  34.     public void showImageAsyn(ImageView imageView, String url, int resId){  

  35.         imageView.setTag(url);  

  36.         Bitmap bitmap = loadImageAsyn(url, getImageCallback(imageView, resId));  

  37.         if(bitmap == null){  

  38.             imageView.setImageResource(resId);  

  39.         }else{  

  40.             imageView.setImageBitmap(bitmap);  

  41.         }  

  42.     }  

  43.     public Bitmap loadImageAsyn(String path, ImageCallback callback){  

  44.         // 判断缓存中是否已经存在该图片  

  45.         if(caches.containsKey(path)){  

  46.             // 取出软引用  

  47.             SoftReference<Bitmap> rf = caches.get(path);  

  48.             // 通过软引用,获取图片  

  49.             Bitmap bitmap = rf.get();  

  50.             // 如果该图片已经被释放,则将该path对应的键从Map中移除掉  

  51.             if(bitmap == null){  

  52.                 caches.remove(path);  

  53.             }else{  

  54.                 // 如果图片未被释放,直接返回该图片  

  55.                 Log.i(TAG, "return image in cache" + path);  

  56.                 return bitmap;  

  57.             }  

  58.         }else{  

  59.             // 如果缓存中不常在该图片,则创建图片下载任务  

  60.             Task task = new Task();  

  61.             task.path = path;  

  62.             task.callback = callback;  

  63.             Log.i(TAG, "new Task ," + path);  

  64.             if(!taskQueue.contains(task)){  

  65.                 taskQueue.add(task);  

  66.                 // 唤醒任务下载队列  

  67.                 synchronized (runnable) {  

  68.                     runnable.notify();  

  69.                 }  

  70.             }  

  71.         }  

  72.         // 缓存中没有图片则返回null  

  73.         return null;  

  74.     }  

  75.     /** 

  76.      *  

  77.      * @param imageView  

  78.      * @param resId 图片加载完成前显示的图片资源ID 

  79.      * @return 

  80.      */  

  81.     private ImageCallback getImageCallback(final ImageView imageView, final int resId){  

  82.         return new ImageCallback() {  

  83.             @Override  

  84.             public void loadImage(String path, Bitmap bitmap) {  

  85.                 if(path.equals(imageView.getTag().toString())){  

  86.                     imageView.setImageBitmap(bitmap);  

  87.                 }else{  

  88.                     imageView.setImageResource(resId);  

  89.                 }  

  90.             }  

  91.         };  

  92.     }  

  93.     private Handler handler = new Handler(){  

  94.         @Override  

  95.         public void handleMessage(Message msg) {  

  96.             // 子线程中返回的下载完成的任务  

  97.             Task task = (Task)msg.obj;  

  98.             // 调用callback对象的loadImage方法,并将图片路径和图片回传给adapter  

  99.             task.callback.loadImage(task.path, task.bitmap);  

  100.         }  

  101.     };  

  102.     private Runnable runnable = new Runnable() {  

  103.         @Override  

  104.         public void run() {  

  105.             while(isRunning){  

  106.                 // 当队列中还有未处理的任务时,执行下载任务  

  107.                 while(taskQueue.size() > 0){  

  108.                     // 获取第一个任务,并将之从任务队列中删除  

  109.                     Task task = taskQueue.remove(0);  

  110.                     // 将下载的图片添加到缓存  

  111.                     task.bitmap = PicUtil.getbitmap(task.path);  

  112.                     caches.put(task.path, new SoftReference<Bitmap>(task.bitmap));  

  113.                     if(handler != null){  

  114.                         // 创建消息对象,并将完成的任务添加到消息对象中  

  115.                         Message msg = handler.obtainMessage();  

  116.                         msg.obj = task;  

  117.                         // 发送消息回主线程  

  118.                         handler.sendMessage(msg);  

  119.                     }  

  120.                 }  

  121.                 //如果队列为空,则令线程等待  

  122.                 synchronized (this) {  

  123.                     try {  

  124.                         this.wait();  

  125.                     } catch (InterruptedException e) {  

  126.                         e.printStackTrace();  

  127.                     }  

  128.                 }  

  129.             }  

  130.         }  

  131.     };  

  132.     //回调接口  

  133.     public interface ImageCallback{  

  134.         void loadImage(String path, Bitmap bitmap);  

  135.     }  

  136.     class Task{  

  137.         // 下载任务的下载路径  

  138.         String path;  

  139.         // 下载的图片  

  140.         Bitmap bitmap;  

  141.         // 回调对象  

  142.         ImageCallback callback;  

  143.         @Override  

  144.         public boolean equals(Object o) {  

  145.             Task task = (Task)o;  

  146.             return task.path.equals(path);  

  147.         }  

  148.     }  

  149. }  

 最后附上PicUtil类的代码,之前忘了贴这个类的代码,不好意识了~~

[java]  view plain copy
  1. public class PicUtil {  

  2.     private static final String TAG = "PicUtil";  

  3.     /** 

  4.      * 根据一个网络连接(URL)获取bitmapDrawable图像 

  5.      *  

  6.      * @param imageUri 

  7.      * @return 

  8.      */  

  9.     public static BitmapDrawable getfriendicon(URL imageUri) {  

  10.         BitmapDrawable icon = null;  

  11.         try {  

  12.             HttpURLConnection hp = (HttpURLConnection) imageUri  

  13.                     .openConnection();  

  14.             icon = new BitmapDrawable(hp.getInputStream());// 将输入流转换成bitmap  

  15.             hp.disconnect();// 关闭连接  

  16.         } catch (Exception e) {  

  17.         }  

  18.         return icon;  

  19.     }  

  20.     /** 

  21.      * 根据一个网络连接(String)获取bitmapDrawable图像 

  22.      *  

  23.      * @param imageUri 

  24.      * @return 

  25.      */  

  26.     public static BitmapDrawable getcontentPic(String imageUri) {  

  27.         URL imgUrl = null;  

  28.         try {  

  29.             imgUrl = new URL(imageUri);  

  30.         } catch (MalformedURLException e1) {  

  31.             e1.printStackTrace();  

  32.         }  

  33.         BitmapDrawable icon = null;  

  34.         try {  

  35.             HttpURLConnection hp = (HttpURLConnection) imgUrl.openConnection();  

  36.             icon = new BitmapDrawable(hp.getInputStream());// 将输入流转换成bitmap  

  37.             hp.disconnect();// 关闭连接  

  38.         } catch (Exception e) {  

  39.         }  

  40.         return icon;  

  41.     }  

  42.     /** 

  43.      * 根据一个网络连接(URL)获取bitmap图像 

  44.      *  

  45.      * @param imageUri 

  46.      * @return 

  47.      */  

  48.     public static Bitmap getusericon(URL imageUri) {  

  49.         // 显示网络上的图片  

  50.         URL myFileUrl = imageUri;  

  51.         Bitmap bitmap = null;  

  52.         try {  

  53.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  

  54.                     .openConnection();  

  55.             conn.setDoInput(true);  

  56.             conn.connect();  

  57.             InputStream is = conn.getInputStream();  

  58.             bitmap = BitmapFactory.decodeStream(is);  

  59.             is.close();  

  60.         } catch (IOException e) {  

  61.             e.printStackTrace();  

  62.         }  

  63.         return bitmap;  

  64.     }  

  65.     /** 

  66.      * 根据一个网络连接(String)获取bitmap图像 

  67.      *  

  68.      * @param imageUri 

  69.      * @return 

  70.      * @throws MalformedURLException 

  71.      */  

  72.     public static Bitmap getbitmap(String imageUri) {  

  73.         // 显示网络上的图片  

  74.         Bitmap bitmap = null;  

  75.         try {  

  76.             URL myFileUrl = new URL(imageUri);  

  77.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  

  78.                     .openConnection();  

  79.             conn.setDoInput(true);  

  80.             conn.connect();  

  81.             InputStream is = conn.getInputStream();  

  82.             bitmap = BitmapFactory.decodeStream(is);  

  83.             is.close();  

  84.             Log.i(TAG, "image download finished." + imageUri);  

  85.         } catch (IOException e) {  

  86.             e.printStackTrace();  

  87.             return null;  

  88.         }  

  89.         return bitmap;  

  90.     }  

  91.     /** 

  92.      * 下载图片 同时写道本地缓存文件中 

  93.      *  

  94.      * @param context 

  95.      * @param imageUri 

  96.      * @return 

  97.      * @throws MalformedURLException 

  98.      */  

  99.     public static Bitmap getbitmapAndwrite(String imageUri) {  

  100.         Bitmap bitmap = null;  

  101.         try {  

  102.             // 显示网络上的图片  

  103.             URL myFileUrl = new URL(imageUri);  

  104.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  

  105.                     .openConnection();  

  106.             conn.setDoInput(true);  

  107.             conn.connect();  

  108.             InputStream is = conn.getInputStream();  

  109.             File cacheFile = FileUtil.getCacheFile(imageUri);  

  110.             BufferedOutputStream bos = null;  

  111.             bos = new BufferedOutputStream(new FileOutputStream(cacheFile));  

  112.             Log.i(TAG, "write file to " + cacheFile.getCanonicalPath());  

  113.             byte[] buf = new byte[1024];  

  114.             int len = 0;  

  115.             // 将网络上的图片存储到本地  

  116.             while ((len = is.read(buf)) > 0) {  

  117.                 bos.write(buf, 0, len);  

  118.             }  

  119.             is.close();  

  120.             bos.close();  

  121.             // 从本地加载图片  

  122.             bitmap = BitmapFactory.decodeFile(cacheFile.getCanonicalPath());  

  123.             String name = MD5Util.MD5(imageUri);  

  124.         } catch (IOException e) {  

  125.             e.printStackTrace();  

  126.         }  

  127.         return bitmap;  

  128.     }  

  129.     public static boolean downpic(String picName, Bitmap bitmap) {  

  130.         boolean nowbol = false;  

  131.         try {  

  132.             File saveFile = new File("/mnt/sdcard/download/weibopic/" + picName  

  133.                     + ".png");  

  134.             if (!saveFile.exists()) {  

  135.                 saveFile.createNewFile();  

  136.             }  

  137.             FileOutputStream saveFileOutputStream;  

  138.             saveFileOutputStream = new FileOutputStream(saveFile);  

  139.             nowbol = bitmap.compress(Bitmap.CompressFormat.PNG, 100,  

  140.                     saveFileOutputStream);  

  141.             saveFileOutputStream.close();  

  142.         } catch (FileNotFoundException e) {  

  143.             e.printStackTrace();  

  144.         } catch (IOException e) {  

  145.             e.printStackTrace();  

  146.         } catch (Exception e) {  

  147.             e.printStackTrace();  

  148.         }  

  149.         return nowbol;  

  150.     }  

  151.     public static void writeTofiles(Context context, Bitmap bitmap,  

  152.             String filename) {  

  153.         BufferedOutputStream outputStream = null;  

  154.         try {  

  155.             outputStream = new BufferedOutputStream(context.openFileOutput(  

  156.                     filename, Context.MODE_PRIVATE));  

  157.             bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);  

  158.         } catch (FileNotFoundException e) {  

  159.             e.printStackTrace();  

  160.         }  

  161.     }  

  162.     /** 

  163.      * 将文件写入缓存系统中 

  164.      *  

  165.      * @param filename 

  166.      * @param is 

  167.      * @return 

  168.      */  

  169.     public static String writefile(Context context, String filename,  

  170.             InputStream is) {  

  171.         BufferedInputStream inputStream = null;  

  172.         BufferedOutputStream outputStream = null;  

  173.         try {  

  174.             inputStream = new BufferedInputStream(is);  

  175.             outputStream = new BufferedOutputStream(context.openFileOutput(  

  176.                     filename, Context.MODE_PRIVATE));  

  177.             byte[] buffer = new byte[1024];  

  178.             int length;  

  179.             while ((length = inputStream.read(buffer)) != -1) {  

  180.                 outputStream.write(buffer, 0, length);  

  181.             }  

  182.         } catch (Exception e) {  

  183.         } finally {  

  184.             if (inputStream != null) {  

  185.                 try {  

  186.                     inputStream.close();  

  187.                 } catch (IOException e) {  

  188.                     e.printStackTrace();  

  189.                 }  

  190.             }  

  191.             if (outputStream != null) {  

  192.                 try {  

  193.                     outputStream.flush();  

  194.                     outputStream.close();  

  195.                 } catch (IOException e) {  

  196.                     e.printStackTrace();  

  197.                 }  

  198.             }  

  199.         }  

  200.         return context.getFilesDir() + "/" + filename + ".jpg";  

  201.     }  

  202.     // 放大缩小图片  

  203.     public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {  

  204.         int width = bitmap.getWidth();  

  205.         int height = bitmap.getHeight();  

  206.         Matrix matrix = new Matrix();  

  207.         float scaleWidht = ((float) w / width);  

  208.         float scaleHeight = ((float) h / height);  

  209.         matrix.postScale(scaleWidht, scaleHeight);  

  210.         Bitmap newbmp = Bitmap.createBitmap(bitmap, 00, width, height,  

  211.                 matrix, true);  

  212.         return newbmp;  

  213.     }  

  214.     // 将Drawable转化为Bitmap  

  215.     public static Bitmap drawableToBitmap(Drawable drawable) {  

  216.         int width = drawable.getIntrinsicWidth();  

  217.         int height = drawable.getIntrinsicHeight();  

  218.         Bitmap bitmap = Bitmap.createBitmap(width, height, drawable  

  219.                 .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888  

  220.                 : Bitmap.Config.RGB_565);  

  221.         Canvas canvas = new Canvas(bitmap);  

  222.         drawable.setBounds(00, width, height);  

  223.         drawable.draw(canvas);  

  224.         return bitmap;  

  225.     }  

  226.     // 获得圆角图片的方法  

  227.     public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {  

  228.         if(bitmap == null){  

  229.             return null;  

  230.         }  

  231.         Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),  

  232.                 bitmap.getHeight(), Config.ARGB_8888);  

  233.         Canvas canvas = new Canvas(output);  

  234.         final int color = 0xff424242;  

  235.         final Paint paint = new Paint();  

  236.         final Rect rect = new Rect(00, bitmap.getWidth(), bitmap.getHeight());  

  237.         final RectF rectF = new RectF(rect);  

  238.         paint.setAntiAlias(true);  

  239.         canvas.drawARGB(0000);  

  240.         paint.setColor(color);  

  241.         canvas.drawRoundRect(rectF, roundPx, roundPx, paint);  

  242.         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  

  243.         canvas.drawBitmap(bitmap, rect, rect, paint);  

  244.         return output;  

  245.     }  

  246.     // 获得带倒影的图片方法  

  247.     public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {  

  248.         final int reflectionGap = 4;  

  249.         int width = bitmap.getWidth();  

  250.         int height = bitmap.getHeight();  

  251.         Matrix matrix = new Matrix();  

  252.         matrix.preScale(1, -1);  

  253.         Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,  

  254.                 width, height / 2, matrix, false);  

  255.         Bitmap bitmapWithReflection = Bitmap.createBitmap(width,  

  256.                 (height + height / 2), Config.ARGB_8888);  

  257.         Canvas canvas = new Canvas(bitmapWithReflection);  

  258.         canvas.drawBitmap(bitmap, 00null);  

  259.         Paint deafalutPaint = new Paint();  

  260.         canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);  

  261.         canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);  

  262.         Paint paint = new Paint();  

  263.         LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,  

  264.                 bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,  

  265.                 0x00ffffff, TileMode.CLAMP);  

  266.         paint.setShader(shader);  

  267.         // Set the Transfer mode to be porter duff and destination in  

  268.         paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));  

  269.         // Draw a rectangle using the paint with our linear gradient  

  270.         canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()  

  271.                 + reflectionGap, paint);  

  272.         return bitmapWithReflection;  

  273.     }  

  274. }  

 FileUtil

[java]  view plain copy
  1. package com.wangge.coupon.util;  

  2. import java.io.File;  

  3. import java.io.IOException;  

  4. import android.os.Environment;  

  5. import android.util.Log;  

  6. import com.wangge.coupon.http.AsynImageLoader;  

  7. public class FileUtil {  

  8.     private static final String TAG = "FileUtil";  

  9.     public static File getCacheFile(String imageUri){  

  10.         File cacheFile = null;  

  11.         try {  

  12.             if (Environment.getExternalStorageState().equals(  

  13.                     Environment.MEDIA_MOUNTED)) {  

  14.                 File sdCardDir = Environment.getExternalStorageDirectory();  

  15.                 String fileName = getFileName(imageUri);  

  16.                 File dir = new File(sdCardDir.getCanonicalPath()  

  17.                         + AsynImageLoader.CACHE_DIR);  

  18.                 if (!dir.exists()) {  

  19.                     dir.mkdirs();  

  20.                 }  

  21.                 cacheFile = new File(dir, fileName);  

  22.                 Log.i(TAG, "exists:" + cacheFile.exists() + ",dir:" + dir + ",file:" + fileName);  

  23.             }    

  24.         } catch (IOException e) {  

  25.             e.printStackTrace();  

  26.             Log.e(TAG, "getCacheFileError:" + e.getMessage());  

  27.         }  

  28.         return cacheFile;  

  29.     }  

  30.     public static String getFileName(String path) {  

  31.         int index = path.lastIndexOf("/");  

  32.         return path.substring(index + 1);  

  33.     }  

  34. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多