【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2992|回复: 0

Android异步加载网络图片

[复制链接]
发表于 2013-1-24 11:59:51 | 显示全部楼层 |阅读模式

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

转自:http://blog.csdn.net/geniusxiaoyu/article/details/7470163

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

使用方法:

  1. AsynImageLoader asynImageLoader = new AsynImageLoader();
  2. asynImageLoader.showImageAsyn(imageView, imageUrl, resId);
复制代码
类代码:
  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.        
  21.         public AsynImageLoader(){
  22.                 // 初始化变量
  23.                 caches = new HashMap<String, SoftReference<Bitmap>>();
  24.                 taskQueue = new ArrayList<AsynImageLoader.Task>();
  25.                 // 启动图片下载线程
  26.                 isRunning = true;
  27.                 new Thread(runnable).start();
  28.         }
  29.        
  30.         /**
  31.          *
  32.          * @param imageView 需要延迟加载图片的对象
  33.          * @param url 图片的URL地址
  34.          * @param resId 图片加载过程中显示的图片资源
  35.          */
  36.         public void showImageAsyn(ImageView imageView, String url, int resId){
  37.                 imageView.setTag(url);
  38.                 Bitmap bitmap = loadImageAsyn(url, getImageCallback(imageView, resId));
  39.                
  40.                 if(bitmap == null){
  41.                         imageView.setImageResource(resId);
  42.                 }else{
  43.                         imageView.setImageBitmap(bitmap);
  44.                 }
  45.         }
  46.        
  47.         public Bitmap loadImageAsyn(String path, ImageCallback callback){
  48.                 // 判断缓存中是否已经存在该图片
  49.                 if(caches.containsKey(path)){
  50.                         // 取出软引用
  51.                         SoftReference<Bitmap> rf = caches.get(path);
  52.                         // 通过软引用,获取图片
  53.                         Bitmap bitmap = rf.get();
  54.                         // 如果该图片已经被释放,则将该path对应的键从Map中移除掉
  55.                         if(bitmap == null){
  56.                                 caches.remove(path);
  57.                         }else{
  58.                                 // 如果图片未被释放,直接返回该图片
  59.                                 Log.i(TAG, "return image in cache" + path);
  60.                                 return bitmap;
  61.                         }
  62.                 }else{
  63.                         // 如果缓存中不常在该图片,则创建图片下载任务
  64.                         Task task = new Task();
  65.                         task.path = path;
  66.                         task.callback = callback;
  67.                         Log.i(TAG, "new Task ," + path);
  68.                         if(!taskQueue.contains(task)){
  69.                                 taskQueue.add(task);
  70.                                 // 唤醒任务下载队列
  71.                                 synchronized (runnable) {
  72.                                         runnable.notify();
  73.                                 }
  74.                         }
  75.                 }
  76.                
  77.                 // 缓存中没有图片则返回null
  78.                 return null;
  79.         }
  80.        
  81.         /**
  82.          *
  83.          * @param imageView
  84.          * @param resId 图片加载完成前显示的图片资源ID
  85.          * @return
  86.          */
  87.         private ImageCallback getImageCallback(final ImageView imageView, final int resId){
  88.                 return new ImageCallback() {
  89.                        
  90.                         @Override
  91.                         public void loadImage(String path, Bitmap bitmap) {
  92.                                 if(path.equals(imageView.getTag().toString())){
  93.                                         imageView.setImageBitmap(bitmap);
  94.                                 }else{
  95.                                         imageView.setImageResource(resId);
  96.                                 }
  97.                         }
  98.                 };
  99.         }
  100.        
  101.         private Handler handler = new Handler(){

  102.                 @Override
  103.                 public void handleMessage(Message msg) {
  104.                         // 子线程中返回的下载完成的任务
  105.                         Task task = (Task)msg.obj;
  106.                         // 调用callback对象的loadImage方法,并将图片路径和图片回传给adapter
  107.                         task.callback.loadImage(task.path, task.bitmap);
  108.                 }
  109.                
  110.         };
  111.        
  112.         private Runnable runnable = new Runnable() {
  113.                
  114.                 @Override
  115.                 public void run() {
  116.                         while(isRunning){
  117.                                 // 当队列中还有未处理的任务时,执行下载任务
  118.                                 while(taskQueue.size() > 0){
  119.                                         // 获取第一个任务,并将之从任务队列中删除
  120.                                         Task task = taskQueue.remove(0);
  121.                                         // 将下载的图片添加到缓存
  122.                                         task.bitmap = PicUtil.getbitmap(task.path);
  123.                                         caches.put(task.path, new SoftReference<Bitmap>(task.bitmap));
  124.                                         if(handler != null){
  125.                                                 // 创建消息对象,并将完成的任务添加到消息对象中
  126.                                                 Message msg = handler.obtainMessage();
  127.                                                 msg.obj = task;
  128.                                                 // 发送消息回主线程
  129.                                                 handler.sendMessage(msg);
  130.                                         }
  131.                                 }
  132.                                
  133.                                 //如果队列为空,则令线程等待
  134.                                 synchronized (this) {
  135.                                         try {
  136.                                                 this.wait();
  137.                                         } catch (InterruptedException e) {
  138.                                                 e.printStackTrace();
  139.                                         }
  140.                                 }
  141.                         }
  142.                 }
  143.         };
  144.        
  145.         //回调接口
  146.         public interface ImageCallback{
  147.                 void loadImage(String path, Bitmap bitmap);
  148.         }
  149.        
  150.         class Task{
  151.                 // 下载任务的下载路径
  152.                 String path;
  153.                 // 下载的图片
  154.                 Bitmap bitmap;
  155.                 // 回调对象
  156.                 ImageCallback callback;
  157.                
  158.                 @Override
  159.                 public boolean equals(Object o) {
  160.                         Task task = (Task)o;
  161.                         return task.path.equals(path);
  162.                 }
  163.         }
  164. }
复制代码
最后附上PicUtil类的代码
  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, 0, 0, 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(0, 0, 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.                
  232.                 Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
  233.                                 bitmap.getHeight(), Config.ARGB_8888);
  234.                 Canvas canvas = new Canvas(output);

  235.                 final int color = 0xff424242;
  236.                 final Paint paint = new Paint();
  237.                 final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
  238.                 final RectF rectF = new RectF(rect);

  239.                 paint.setAntiAlias(true);
  240.                 canvas.drawARGB(0, 0, 0, 0);
  241.                 paint.setColor(color);
  242.                 canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

  243.                 paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  244.                 canvas.drawBitmap(bitmap, rect, rect, paint);
  245.                 return output;
  246.         }

  247.         // 获得带倒影的图片方法
  248.         public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
  249.                 final int reflectionGap = 4;
  250.                 int width = bitmap.getWidth();
  251.                 int height = bitmap.getHeight();

  252.                 Matrix matrix = new Matrix();
  253.                 matrix.preScale(1, -1);

  254.                 Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,
  255.                                 width, height / 2, matrix, false);

  256.                 Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
  257.                                 (height + height / 2), Config.ARGB_8888);

  258.                 Canvas canvas = new Canvas(bitmapWithReflection);
  259.                 canvas.drawBitmap(bitmap, 0, 0, null);
  260.                 Paint deafalutPaint = new Paint();
  261.                 canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);

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

  263.                 Paint paint = new Paint();
  264.                 LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
  265.                                 bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
  266.                                 0x00ffffff, TileMode.CLAMP);
  267.                 paint.setShader(shader);
  268.                 // Set the Transfer mode to be porter duff and destination in
  269.                 paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
  270.                 // Draw a rectangle using the paint with our linear gradient
  271.                 canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
  272.                                 + reflectionGap, paint);

  273.                 return bitmapWithReflection;
  274.         }

  275. }
复制代码
FileUtil
  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.                
  29.                 return cacheFile;
  30.         }
  31.        
  32.         public static String getFileName(String path) {
  33.                 int index = path.lastIndexOf("/");
  34.                 return path.substring(index + 1);
  35.         }
  36. }
复制代码
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2024-9-27 22:17

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表