AsyncTask异步下载图片


这个例子是利用AsyncTask异步下载图片,下载时先将网络图片下载到本地cache目录保存,以imagUrl的图片文件名保存,如果有同名文件在cache目录就从本地加载。

布局文件,先用一个图片占位:
Java代码 复制代码  收藏代码
  1. <ImageView  
  2.           android:id="@+id/image"  
  3.           android:layout_width="fill_parent"  
  4.           android:layout_height="fill_parent"  
  5.           android:layout_gravity="center_horizontal"  
  6.           android:layout_marginTop="20dip"  
  7.           android:src="@drawable/product_default_icon" />  
  <ImageView
            android:id="@+id/image"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="20dip"
            android:src="@drawable/product_default_icon" />


Java代码 复制代码  收藏代码
  1. private Context context = AsyncTaskDemo.this;  
  2.     private ImageView image;  
  3.     //图片地址  
  4.     private String imageUrl = "http://dl.iteye.com/upload/attachment/0080/1571/2b9a099a-0a7b-3a60-909e-97a8316716cb.jpg";  
  5.   
  6.       
  7.     public void onCreate(Bundle savedInstanceState) {  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.asynctask);  
  10.         getWidget();  
  11.         loadImage(imageUrl);  
  12.     }  
  13.   
  14.     /** 获得组件 */  
  15.     public void getWidget() {  
  16.         image = (ImageView) findViewById(R.id.image);  
  17.     }  
  18.   
  19.     private void loadImage(final String imageUrl) {  
  20.   
  21.         ImageAsyncLoader asyncImageLoader = new ImageAsyncLoader();  
  22.   
  23.         // 异步加载图片  
  24.         Drawable cachedImage = asyncImageLoader.loadDrawable(context, imageUrl, new ImageCallback() {  
  25.             public void imageLoaded(Drawable imageDrawable, String imageUrl) {  
  26.                 if (imageDrawable != null) {  
  27.                     image.setImageDrawable(ImageAsyncLoader.zoomDrawable(imageDrawable, ImageAsyncLoader.dip2px(context, 150), ImageAsyncLoader.dip2px(context, 150)));  
  28.                 }  
  29.             }  
  30.         });  
  31.         if (cachedImage != null) {  
  32.             image.setImageDrawable(ImageAsyncLoader.zoomDrawable(cachedImage, ImageAsyncLoader.dip2px(context, 150), ImageAsyncLoader.dip2px(context, 150)));  
  33.         }  
  34.     }  
private Context context = AsyncTaskDemo.this;
	private ImageView image;
	//图片地址
	private String imageUrl = "http://dl.iteye.com/upload/attachment/0080/1571/2b9a099a-0a7b-3a60-909e-97a8316716cb.jpg";

	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.asynctask);
		getWidget();
		loadImage(imageUrl);
	}

	/** 获得组件 */
	public void getWidget() {
		image = (ImageView) findViewById(R.id.image);
	}

	private void loadImage(final String imageUrl) {

		ImageAsyncLoader asyncImageLoader = new ImageAsyncLoader();

		// 异步加载图片
		Drawable cachedImage = asyncImageLoader.loadDrawable(context, imageUrl, new ImageCallback() {
			public void imageLoaded(Drawable imageDrawable, String imageUrl) {
				if (imageDrawable != null) {
					image.setImageDrawable(ImageAsyncLoader.zoomDrawable(imageDrawable, ImageAsyncLoader.dip2px(context, 150), ImageAsyncLoader.dip2px(context, 150)));
				}
			}
		});
		if (cachedImage != null) {
			image.setImageDrawable(ImageAsyncLoader.zoomDrawable(cachedImage, ImageAsyncLoader.dip2px(context, 150), ImageAsyncLoader.dip2px(context, 150)));
		}
	}

图片异步加载工具:
Java代码 复制代码  收藏代码
  1. private HashMap<String, SoftReference<Drawable>> cacheMap = null;  
  2.     private BlockingQueue<Runnable> queue = null;  
  3.     private ThreadPoolExecutor executor = null;  
  4.   
  5.     public ImageAsyncLoader() {  
  6.         cacheMap = new HashMap<String, SoftReference<Drawable>>();  
  7.   
  8.         queue = new LinkedBlockingQueue<Runnable>();  
  9.         /** 
  10.          * 线程池维护线程的最少数量2 <br> 
  11.          * 线程池维护线程的最大数量10<br> 
  12.          * 线程池维护线程所允许的空闲时间180秒 
  13.          */  
  14.         executor = new ThreadPoolExecutor(210180, TimeUnit.SECONDS, queue);  
  15.     }  
  16.   
  17.     public Drawable loadDrawable(final Context context, final String imageUrl, final ImageCallback imageCallback) {  
  18.         if (cacheMap.containsKey(imageUrl)) {  
  19.             SoftReference<Drawable> softReference = cacheMap.get(imageUrl);  
  20.             Drawable drawable = softReference.get();  
  21.             if (drawable != null) {  
  22.                 return drawable;  
  23.             }  
  24.         }  
  25.   
  26.         final Handler handler = new Handler() {  
  27.             public void handleMessage(Message message) {  
  28.                 imageCallback.imageLoaded((Drawable) message.obj, imageUrl);  
  29.             }  
  30.         };  
  31.   
  32.         // 将任务添加到线程池  
  33.         executor.execute(new Runnable() {  
  34.             public void run() {  
  35.                 // 根据URL加载图片  
  36.                 Drawable drawable = loadImageFromUrl(context, imageUrl);  
  37.   
  38.                 // 图片资源不为空是创建软引用  
  39.                 if (null != drawable)  
  40.                     cacheMap.put(imageUrl, new SoftReference<Drawable>(drawable));  
  41.   
  42.                 Message message = handler.obtainMessage(0, drawable);  
  43.                 handler.sendMessage(message);  
  44.             }  
  45.         });  
  46.   
  47.         return null;  
  48.     }  
  49.   
  50.     // 网络图片先下载到本地cache目录保存,以imagUrl的图片文件名保存,如果有同名文件在cache目录就从本地加载  
  51.     public static Drawable loadImageFromUrl(Context context, String imageUrl) {  
  52.         Drawable drawable = null;  
  53.   
  54.         if (imageUrl == null)  
  55.             return null;  
  56.         String fileName = "";  
  57.   
  58.         // 获取url中图片的文件名与后缀  
  59.         if (imageUrl != null && imageUrl.length() != 0) {  
  60.             fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);  
  61.         }  
  62.   
  63.         // 根据图片的名称创建文件(不存在:创建)  
  64.         File file = new File(context.getCacheDir(), fileName);  
  65.   
  66.         // 如果在缓存中找不到指定图片则下载  
  67.         if (!file.exists() && !file.isDirectory()) {  
  68.             try {  
  69.                 // 从网络上下载图片并写入文件  
  70.                 FileOutputStream fos = new FileOutputStream(file);  
  71.                 InputStream is = new URL(imageUrl).openStream();  
  72.                 int data = is.read();  
  73.                 while (data != -1) {  
  74.                     fos.write(data);  
  75.                     data = is.read();  
  76.                 }  
  77.                 fos.close();  
  78.                 is.close();  
  79.   
  80.                 drawable = Drawable.createFromPath(file.toString());  
  81.             } catch (IOException e) {  
  82.                 e.printStackTrace();  
  83.             }  
  84.         }  
  85.         // 如果缓存中有则直接使用缓存中的图片  
  86.         else {  
  87.             // System.out.println(file.isDirectory() + " " + file.getName());  
  88.             drawable = Drawable.createFromPath(file.toString());  
  89.         }  
  90.         return drawable;  
  91.     }  
  92.   
  93.     public interface ImageCallback {  
  94.         public void imageLoaded(Drawable imageDrawable, String imageUrl);  
  95.     }  
private HashMap<String, SoftReference<Drawable>> cacheMap = null;
	private BlockingQueue<Runnable> queue = null;
	private ThreadPoolExecutor executor = null;

	public ImageAsyncLoader() {
		cacheMap = new HashMap<String, SoftReference<Drawable>>();

		queue = new LinkedBlockingQueue<Runnable>();
		/**
		 * 线程池维护线程的最少数量2 <br>
		 * 线程池维护线程的最大数量10<br>
		 * 线程池维护线程所允许的空闲时间180秒
		 */
		executor = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, queue);
	}

	public Drawable loadDrawable(final Context context, final String imageUrl, final ImageCallback imageCallback) {
		if (cacheMap.containsKey(imageUrl)) {
			SoftReference<Drawable> softReference = cacheMap.get(imageUrl);
			Drawable drawable = softReference.get();
			if (drawable != null) {
				return drawable;
			}
		}

		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
			}
		};

		// 将任务添加到线程池
		executor.execute(new Runnable() {
			public void run() {
				// 根据URL加载图片
				Drawable drawable = loadImageFromUrl(context, imageUrl);

				// 图片资源不为空是创建软引用
				if (null != drawable)
					cacheMap.put(imageUrl, new SoftReference<Drawable>(drawable));

				Message message = handler.obtainMessage(0, drawable);
				handler.sendMessage(message);
			}
		});

		return null;
	}

	// 网络图片先下载到本地cache目录保存,以imagUrl的图片文件名保存,如果有同名文件在cache目录就从本地加载
	public static Drawable loadImageFromUrl(Context context, String imageUrl) {
		Drawable drawable = null;

		if (imageUrl == null)
			return null;
		String fileName = "";

		// 获取url中图片的文件名与后缀
		if (imageUrl != null && imageUrl.length() != 0) {
			fileName = imageUrl.substring(imageUrl.lastIndexOf("/") + 1);
		}

		// 根据图片的名称创建文件(不存在:创建)
		File file = new File(context.getCacheDir(), fileName);

		// 如果在缓存中找不到指定图片则下载
		if (!file.exists() && !file.isDirectory()) {
			try {
				// 从网络上下载图片并写入文件
				FileOutputStream fos = new FileOutputStream(file);
				InputStream is = new URL(imageUrl).openStream();
				int data = is.read();
				while (data != -1) {
					fos.write(data);
					data = is.read();
				}
				fos.close();
				is.close();

				drawable = Drawable.createFromPath(file.toString());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		// 如果缓存中有则直接使用缓存中的图片
		else {
			// System.out.println(file.isDirectory() + " " + file.getName());
			drawable = Drawable.createFromPath(file.toString());
		}
		return drawable;
	}

	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable, String imageUrl);
	}


常用图片处理方法:
Java代码 复制代码  收藏代码
  1. /** 
  2.      * 缩放Drawable 
  3.      *  
  4.      * @param drawable 
  5.      * @param w 缩放后的宽 
  6.      * @param h 缩放后的高 
  7.      * @return Drawable 
  8.      */  
  9.     public static Drawable zoomDrawable(Drawable drawable, int w, int h) {  
  10.         int width = drawable.getIntrinsicWidth();  
  11.         int height = drawable.getIntrinsicHeight();  
  12.         // drawable转换成bitmap  
  13.         Bitmap oldbmp = drawableToBitmap(drawable);  
  14.         // 创建操作图片用的Matrix对象  
  15.         Matrix matrix = new Matrix();  
  16.         // 计算缩放比例  
  17.         float scaleWidth = ((float) w / width);  
  18.         float scaleHeight = ((float) h / height);  
  19.         matrix.postScale(scaleWidth, scaleHeight);  
  20.         // 设置缩放比例  
  21.         Bitmap newbmp = Bitmap.createBitmap(oldbmp, 00, width, height, matrix, true);  
  22.         return new BitmapDrawable(newbmp);  
  23.     }  
  24.   
  25.     /** 
  26.      * 将drawable转换成bitmap 
  27.      *  
  28.      * @param drawable 
  29.      * @return Bitmap 
  30.      */  
  31.     private static Bitmap drawableToBitmap(Drawable drawable) {  
  32.         // 取drawable的长宽  
  33.         int width = drawable.getIntrinsicWidth();  
  34.         int height = drawable.getIntrinsicHeight();  
  35.         Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; // 取drawable的颜色格式  
  36.   
  37.         Bitmap bitmap = Bitmap.createBitmap(width, height, config);  
  38.         Canvas canvas = new Canvas(bitmap);  
  39.         drawable.setBounds(00, width, height);  
  40.         drawable.draw(canvas);  
  41.         return bitmap;  
  42.     }  
  43.   
  44.     /** 
  45.      * 单位转换:dip => px 
  46.      *  
  47.      * @param ctx 上下文环境 
  48.      * @param dipValue 
  49.      * @return 
  50.      */  
  51.     public static int dip2px(Context ctx, int dipValue) {  
  52.         final float scale = ctx.getResources().getDisplayMetrics().density;  
  53.         return (int) (dipValue * scale);  
  54.     }  
/**
	 * 缩放Drawable
	 * 
	 * @param drawable
	 * @param w 缩放后的宽
	 * @param h 缩放后的高
	 * @return Drawable
	 */
	public static Drawable zoomDrawable(Drawable drawable, int w, int h) {
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		// drawable转换成bitmap
		Bitmap oldbmp = drawableToBitmap(drawable);
		// 创建操作图片用的Matrix对象
		Matrix matrix = new Matrix();
		// 计算缩放比例
		float scaleWidth = ((float) w / width);
		float scaleHeight = ((float) h / height);
		matrix.postScale(scaleWidth, scaleHeight);
		// 设置缩放比例
		Bitmap newbmp = Bitmap.createBitmap(oldbmp, 0, 0, width, height, matrix, true);
		return new BitmapDrawable(newbmp);
	}

	/**
	 * 将drawable转换成bitmap
	 * 
	 * @param drawable
	 * @return Bitmap
	 */
	private static Bitmap drawableToBitmap(Drawable drawable) {
		// 取drawable的长宽
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565; // 取drawable的颜色格式

		Bitmap bitmap = Bitmap.createBitmap(width, height, config);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, width, height);
		drawable.draw(canvas);
		return bitmap;
	}

	/**
	 * 单位转换:dip => px
	 * 
	 * @param ctx 上下文环境
	 * @param dipValue
	 * @return
	 */
	public static int dip2px(Context ctx, int dipValue) {
		final float scale = ctx.getResources().getDisplayMetrics().density;
		return (int) (dipValue * scale);
	}


配置文件:
Java代码 复制代码  收藏代码
  1. <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />  
  2.     <uses-permission android:name="android.permission.INTERNET" />  

转自:http://www.iteye.com/topic/1129126

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值