Android 异步加载图片(AsyncImageLoader)

来源:互联网 发布:手机海报拼图软件 编辑:程序博客网 时间:2024/06/07 09:12

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

布局文件,先用一个图片占位: 

  <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" />

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)));}}

图片异步加载工具

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);}

常用图片处理方法

/** * 缩放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转换成bitmapBitmap 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);}

配置文件

<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /><uses-permission android:name="android.permission.INTERNET" />


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