这个例子是利用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)));}}

图片异步加载:
/** * SoftReference的主要特点是据有较强的引用功能。 *  只有当内存不够的时候,才进行回收这类内存,因此在内存足够的时候,它们通常不被回收。  *  另外,这些引用对象还能保证在Java抛出OutOfMemory 异常之前,被设置为null。 *  它可以用于实现一些常用图片的缓存,实现Cache的功能,保证最大限度的使用内存而不引起OutOfMemory。 */private HashMap<String, SoftReference<Drawable>> cacheMap = null;private BlockingQueue<Runnable> queue = null;private ThreadPoolExecutor executor = null;public interface ImageCallback {public void imageLoaded(Drawable imageDrawable, String imageUrl);}public ImageAsyncLoader() {cacheMap = new HashMap<String, SoftReference<Drawable>>();/** * 一个基于已链接节点的、范围任意的 blocking queue。 * 此队列按 FIFO(先进先出)排序元素。 * 队列的头部 是在队列中时间最长的元素。 * 队列的尾部 是在队列中时间最短的元素。 * 新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素。 * 链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。 */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 {drawable = Drawable.createFromPath(file.toString());}return drawable;}


常用图片处理方法:
/** * 缩放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" />

更多相关文章

  1. Android图片加载框架Picasso最全使用教程 一
  2. Android更新Ui线程的四个方法
  3. android checkbox 未选中状态 已选中状态 替换成自己的图片
  4. Android 控件之Gallery和ImageSwitcher图片切换器
  5. Android深入浅出系列课程---Lesson12 AFF110525_Android多线程系
  6. android学习笔记之多线程学习
  7. android中使用Thumbnails批量加载sdcard中的缩略图片

随机推荐

  1. Adding prebuilt shared library to Andr
  2. android 启动报错
  3. android 日历组件(CalendarView)
  4. 2019博客汇总
  5. System Permissions—— android系统权限
  6. PC和Android(安卓)adb通信
  7. linaro pandaboard android 编译kernel
  8. 手把手叫你用android 调研web services
  9. 【Android 基础7.1 7.2】AsyncTask & Asy
  10. android Draw