zoukankan      html  css  js  c++  java
  • Android异步加载网络图片

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

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

    使用方法:

    [java] view plaincopy
    1. AsynImageLoader asynImageLoader = new AsynImageLoader();  
    2. asynImageLoader.showImageAsyn(imageView, imageUrl, resId);  


     

     

    类代码:

    [java] view plaincopy
    1. package com.wangge.uumao.http;  
    2.   
    3. import java.lang.ref.SoftReference;  
    4. import java.util.ArrayList;  
    5. import java.util.HashMap;  
    6. import java.util.List;  
    7. import java.util.Map;  
    8.   
    9. import android.graphics.Bitmap;  
    10. import android.os.Handler;  
    11. import android.os.Message;  
    12. import android.util.Log;  
    13. import android.widget.ImageView;  
    14.   
    15. import com.wangge.uumao.util.PicUtil;  
    16.   
    17. public class AsynImageLoader {  
    18.     private static final String TAG = "AsynImageLoader";  
    19.     // 缓存下载过的图片的Map  
    20.     private Map<String, SoftReference<Bitmap>> caches;  
    21.     // 任务队列  
    22.     private List<Task> taskQueue;  
    23.     private boolean isRunning = false;  
    24.       
    25.     public AsynImageLoader(){  
    26.         // 初始化变量  
    27.         caches = new HashMap<String, SoftReference<Bitmap>>();  
    28.         taskQueue = new ArrayList<AsynImageLoader.Task>();  
    29.         // 启动图片下载线程  
    30.         isRunning = true;  
    31.         new Thread(runnable).start();  
    32.     }  
    33.       
    34.     /** 
    35.      *  
    36.      * @param imageView 需要延迟加载图片的对象 
    37.      * @param url 图片的URL地址 
    38.      * @param resId 图片加载过程中显示的图片资源 
    39.      */  
    40.     public void showImageAsyn(ImageView imageView, String url, int resId){  
    41.         imageView.setTag(url);  
    42.         Bitmap bitmap = loadImageAsyn(url, getImageCallback(imageView, resId));  
    43.           
    44.         if(bitmap == null){  
    45.             imageView.setImageResource(resId);  
    46.         }else{  
    47.             imageView.setImageBitmap(bitmap);  
    48.         }  
    49.     }  
    50.       
    51.     public Bitmap loadImageAsyn(String path, ImageCallback callback){  
    52.         // 判断缓存中是否已经存在该图片  
    53.         if(caches.containsKey(path)){  
    54.             // 取出软引用  
    55.             SoftReference<Bitmap> rf = caches.get(path);  
    56.             // 通过软引用,获取图片  
    57.             Bitmap bitmap = rf.get();  
    58.             // 如果该图片已经被释放,则将该path对应的键从Map中移除掉  
    59.             if(bitmap == null){  
    60.                 caches.remove(path);  
    61.             }else{  
    62.                 // 如果图片未被释放,直接返回该图片  
    63.                 Log.i(TAG, "return image in cache" + path);  
    64.                 return bitmap;  
    65.             }  
    66.         }else{  
    67.             // 如果缓存中不常在该图片,则创建图片下载任务  
    68.             Task task = new Task();  
    69.             task.path = path;  
    70.             task.callback = callback;  
    71.             Log.i(TAG, "new Task ," + path);  
    72.             if(!taskQueue.contains(task)){  
    73.                 taskQueue.add(task);  
    74.                 // 唤醒任务下载队列  
    75.                 synchronized (runnable) {  
    76.                     runnable.notify();  
    77.                 }  
    78.             }  
    79.         }  
    80.           
    81.         // 缓存中没有图片则返回null  
    82.         return null;  
    83.     }  
    84.       
    85.     /** 
    86.      *  
    87.      * @param imageView  
    88.      * @param resId 图片加载完成前显示的图片资源ID 
    89.      * @return 
    90.      */  
    91.     private ImageCallback getImageCallback(final ImageView imageView, final int resId){  
    92.         return new ImageCallback() {  
    93.               
    94.             @Override  
    95.             public void loadImage(String path, Bitmap bitmap) {  
    96.                 if(path.equals(imageView.getTag().toString())){  
    97.                     imageView.setImageBitmap(bitmap);  
    98.                 }else{  
    99.                     imageView.setImageResource(resId);  
    100.                 }  
    101.             }  
    102.         };  
    103.     }  
    104.       
    105.     private Handler handler = new Handler(){  
    106.   
    107.         @Override  
    108.         public void handleMessage(Message msg) {  
    109.             // 子线程中返回的下载完成的任务  
    110.             Task task = (Task)msg.obj;  
    111.             // 调用callback对象的loadImage方法,并将图片路径和图片回传给adapter  
    112.             task.callback.loadImage(task.path, task.bitmap);  
    113.         }  
    114.           
    115.     };  
    116.       
    117.     private Runnable runnable = new Runnable() {  
    118.           
    119.         @Override  
    120.         public void run() {  
    121.             while(isRunning){  
    122.                 // 当队列中还有未处理的任务时,执行下载任务  
    123.                 while(taskQueue.size() > 0){  
    124.                     // 获取第一个任务,并将之从任务队列中删除  
    125.                     Task task = taskQueue.remove(0);  
    126.                     // 将下载的图片添加到缓存  
    127.                     task.bitmap = PicUtil.getbitmap(task.path);  
    128.                     caches.put(task.path, new SoftReference<Bitmap>(task.bitmap));  
    129.                     if(handler != null){  
    130.                         // 创建消息对象,并将完成的任务添加到消息对象中  
    131.                         Message msg = handler.obtainMessage();  
    132.                         msg.obj = task;  
    133.                         // 发送消息回主线程  
    134.                         handler.sendMessage(msg);  
    135.                     }  
    136.                 }  
    137.                   
    138.                 //如果队列为空,则令线程等待  
    139.                 synchronized (this) {  
    140.                     try {  
    141.                         this.wait();  
    142.                     } catch (InterruptedException e) {  
    143.                         e.printStackTrace();  
    144.                     }  
    145.                 }  
    146.             }  
    147.         }  
    148.     };  
    149.       
    150.     //回调接口  
    151.     public interface ImageCallback{  
    152.         void loadImage(String path, Bitmap bitmap);  
    153.     }  
    154.       
    155.     class Task{  
    156.         // 下载任务的下载路径  
    157.         String path;  
    158.         // 下载的图片  
    159.         Bitmap bitmap;  
    160.         // 回调对象  
    161.         ImageCallback callback;  
    162.           
    163.         @Override  
    164.         public boolean equals(Object o) {  
    165.             Task task = (Task)o;  
    166.             return task.path.equals(path);  
    167.         }  
    168.     }  
    169. }  


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

    [java] view plaincopy
    1. public class PicUtil {  
    2.     private static final String TAG = "PicUtil";  
    3.   
    4.     /** 
    5.      * 根据一个网络连接(URL)获取bitmapDrawable图像 
    6.      *  
    7.      * @param imageUri 
    8.      * @return 
    9.      */  
    10.     public static BitmapDrawable getfriendicon(URL imageUri) {  
    11.   
    12.         BitmapDrawable icon = null;  
    13.         try {  
    14.             HttpURLConnection hp = (HttpURLConnection) imageUri  
    15.                     .openConnection();  
    16.             icon = new BitmapDrawable(hp.getInputStream());// 将输入流转换成bitmap  
    17.             hp.disconnect();// 关闭连接  
    18.         } catch (Exception e) {  
    19.         }  
    20.         return icon;  
    21.     }  
    22.   
    23.     /** 
    24.      * 根据一个网络连接(String)获取bitmapDrawable图像 
    25.      *  
    26.      * @param imageUri 
    27.      * @return 
    28.      */  
    29.     public static BitmapDrawable getcontentPic(String imageUri) {  
    30.         URL imgUrl = null;  
    31.         try {  
    32.             imgUrl = new URL(imageUri);  
    33.         } catch (MalformedURLException e1) {  
    34.             e1.printStackTrace();  
    35.         }  
    36.         BitmapDrawable icon = null;  
    37.         try {  
    38.             HttpURLConnection hp = (HttpURLConnection) imgUrl.openConnection();  
    39.             icon = new BitmapDrawable(hp.getInputStream());// 将输入流转换成bitmap  
    40.             hp.disconnect();// 关闭连接  
    41.         } catch (Exception e) {  
    42.         }  
    43.         return icon;  
    44.     }  
    45.   
    46.     /** 
    47.      * 根据一个网络连接(URL)获取bitmap图像 
    48.      *  
    49.      * @param imageUri 
    50.      * @return 
    51.      */  
    52.     public static Bitmap getusericon(URL imageUri) {  
    53.         // 显示网络上的图片  
    54.         URL myFileUrl = imageUri;  
    55.         Bitmap bitmap = null;  
    56.         try {  
    57.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  
    58.                     .openConnection();  
    59.             conn.setDoInput(true);  
    60.             conn.connect();  
    61.             InputStream is = conn.getInputStream();  
    62.             bitmap = BitmapFactory.decodeStream(is);  
    63.             is.close();  
    64.         } catch (IOException e) {  
    65.             e.printStackTrace();  
    66.         }  
    67.         return bitmap;  
    68.     }  
    69.   
    70.     /** 
    71.      * 根据一个网络连接(String)获取bitmap图像 
    72.      *  
    73.      * @param imageUri 
    74.      * @return 
    75.      * @throws MalformedURLException 
    76.      */  
    77.     public static Bitmap getbitmap(String imageUri) {  
    78.         // 显示网络上的图片  
    79.         Bitmap bitmap = null;  
    80.         try {  
    81.             URL myFileUrl = new URL(imageUri);  
    82.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  
    83.                     .openConnection();  
    84.             conn.setDoInput(true);  
    85.             conn.connect();  
    86.             InputStream is = conn.getInputStream();  
    87.             bitmap = BitmapFactory.decodeStream(is);  
    88.             is.close();  
    89.   
    90.             Log.i(TAG, "image download finished." + imageUri);  
    91.         } catch (IOException e) {  
    92.             e.printStackTrace();  
    93.             return null;  
    94.         }  
    95.         return bitmap;  
    96.     }  
    97.   
    98.     /** 
    99.      * 下载图片 同时写道本地缓存文件中 
    100.      *  
    101.      * @param context 
    102.      * @param imageUri 
    103.      * @return 
    104.      * @throws MalformedURLException 
    105.      */  
    106.     public static Bitmap getbitmapAndwrite(String imageUri) {  
    107.         Bitmap bitmap = null;  
    108.         try {  
    109.             // 显示网络上的图片  
    110.             URL myFileUrl = new URL(imageUri);  
    111.             HttpURLConnection conn = (HttpURLConnection) myFileUrl  
    112.                     .openConnection();  
    113.             conn.setDoInput(true);  
    114.             conn.connect();  
    115.   
    116.             InputStream is = conn.getInputStream();  
    117.             File cacheFile = FileUtil.getCacheFile(imageUri);  
    118.             BufferedOutputStream bos = null;  
    119.             bos = new BufferedOutputStream(new FileOutputStream(cacheFile));  
    120.             Log.i(TAG, "write file to " + cacheFile.getCanonicalPath());  
    121.   
    122.             byte[] buf = new byte[1024];  
    123.             int len = 0;  
    124.             // 将网络上的图片存储到本地  
    125.             while ((len = is.read(buf)) > 0) {  
    126.                 bos.write(buf, 0, len);  
    127.             }  
    128.   
    129.             is.close();  
    130.             bos.close();  
    131.   
    132.             // 从本地加载图片  
    133.             bitmap = BitmapFactory.decodeFile(cacheFile.getCanonicalPath());  
    134.             String name = MD5Util.MD5(imageUri);  
    135.   
    136.         } catch (IOException e) {  
    137.             e.printStackTrace();  
    138.         }  
    139.         return bitmap;  
    140.     }  
    141.   
    142.     public static boolean downpic(String picName, Bitmap bitmap) {  
    143.         boolean nowbol = false;  
    144.         try {  
    145.             File saveFile = new File("/mnt/sdcard/download/weibopic/" + picName  
    146.                     + ".png");  
    147.             if (!saveFile.exists()) {  
    148.                 saveFile.createNewFile();  
    149.             }  
    150.             FileOutputStream saveFileOutputStream;  
    151.             saveFileOutputStream = new FileOutputStream(saveFile);  
    152.             nowbol = bitmap.compress(Bitmap.CompressFormat.PNG, 100,  
    153.                     saveFileOutputStream);  
    154.             saveFileOutputStream.close();  
    155.         } catch (FileNotFoundException e) {  
    156.             e.printStackTrace();  
    157.         } catch (IOException e) {  
    158.             e.printStackTrace();  
    159.         } catch (Exception e) {  
    160.             e.printStackTrace();  
    161.         }  
    162.         return nowbol;  
    163.     }  
    164.   
    165.     public static void writeTofiles(Context context, Bitmap bitmap,  
    166.             String filename) {  
    167.         BufferedOutputStream outputStream = null;  
    168.         try {  
    169.             outputStream = new BufferedOutputStream(context.openFileOutput(  
    170.                     filename, Context.MODE_PRIVATE));  
    171.             bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);  
    172.         } catch (FileNotFoundException e) {  
    173.             e.printStackTrace();  
    174.         }  
    175.     }  
    176.   
    177.     /** 
    178.      * 将文件写入缓存系统中 
    179.      *  
    180.      * @param filename 
    181.      * @param is 
    182.      * @return 
    183.      */  
    184.     public static String writefile(Context context, String filename,  
    185.             InputStream is) {  
    186.         BufferedInputStream inputStream = null;  
    187.         BufferedOutputStream outputStream = null;  
    188.         try {  
    189.             inputStream = new BufferedInputStream(is);  
    190.             outputStream = new BufferedOutputStream(context.openFileOutput(  
    191.                     filename, Context.MODE_PRIVATE));  
    192.             byte[] buffer = new byte[1024];  
    193.             int length;  
    194.             while ((length = inputStream.read(buffer)) != -1) {  
    195.                 outputStream.write(buffer, 0, length);  
    196.             }  
    197.         } catch (Exception e) {  
    198.         } finally {  
    199.             if (inputStream != null) {  
    200.                 try {  
    201.                     inputStream.close();  
    202.                 } catch (IOException e) {  
    203.                     e.printStackTrace();  
    204.                 }  
    205.             }  
    206.             if (outputStream != null) {  
    207.                 try {  
    208.                     outputStream.flush();  
    209.                     outputStream.close();  
    210.                 } catch (IOException e) {  
    211.                     e.printStackTrace();  
    212.                 }  
    213.             }  
    214.         }  
    215.         return context.getFilesDir() + "/" + filename + ".jpg";  
    216.     }  
    217.   
    218.     // 放大缩小图片  
    219.     public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) {  
    220.         int width = bitmap.getWidth();  
    221.         int height = bitmap.getHeight();  
    222.         Matrix matrix = new Matrix();  
    223.         float scaleWidht = ((float) w / width);  
    224.         float scaleHeight = ((float) h / height);  
    225.         matrix.postScale(scaleWidht, scaleHeight);  
    226.         Bitmap newbmp = Bitmap.createBitmap(bitmap, 00, width, height,  
    227.                 matrix, true);  
    228.         return newbmp;  
    229.     }  
    230.   
    231.     // 将Drawable转化为Bitmap  
    232.     public static Bitmap drawableToBitmap(Drawable drawable) {  
    233.         int width = drawable.getIntrinsicWidth();  
    234.         int height = drawable.getIntrinsicHeight();  
    235.         Bitmap bitmap = Bitmap.createBitmap(width, height, drawable  
    236.                 .getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888  
    237.                 : Bitmap.Config.RGB_565);  
    238.         Canvas canvas = new Canvas(bitmap);  
    239.         drawable.setBounds(00, width, height);  
    240.         drawable.draw(canvas);  
    241.         return bitmap;  
    242.   
    243.     }  
    244.   
    245.     // 获得圆角图片的方法  
    246.     public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {  
    247.         if(bitmap == null){  
    248.             return null;  
    249.         }  
    250.           
    251.         Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),  
    252.                 bitmap.getHeight(), Config.ARGB_8888);  
    253.         Canvas canvas = new Canvas(output);  
    254.   
    255.         final int color = 0xff424242;  
    256.         final Paint paint = new Paint();  
    257.         final Rect rect = new Rect(00, bitmap.getWidth(), bitmap.getHeight());  
    258.         final RectF rectF = new RectF(rect);  
    259.   
    260.         paint.setAntiAlias(true);  
    261.         canvas.drawARGB(0000);  
    262.         paint.setColor(color);  
    263.         canvas.drawRoundRect(rectF, roundPx, roundPx, paint);  
    264.   
    265.         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));  
    266.         canvas.drawBitmap(bitmap, rect, rect, paint);  
    267.         return output;  
    268.     }  
    269.   
    270.     // 获得带倒影的图片方法  
    271.     public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {  
    272.         final int reflectionGap = 4;  
    273.         int width = bitmap.getWidth();  
    274.         int height = bitmap.getHeight();  
    275.   
    276.         Matrix matrix = new Matrix();  
    277.         matrix.preScale(1, -1);  
    278.   
    279.         Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,  
    280.                 width, height / 2, matrix, false);  
    281.   
    282.         Bitmap bitmapWithReflection = Bitmap.createBitmap(width,  
    283.                 (height + height / 2), Config.ARGB_8888);  
    284.   
    285.         Canvas canvas = new Canvas(bitmapWithReflection);  
    286.         canvas.drawBitmap(bitmap, 00null);  
    287.         Paint deafalutPaint = new Paint();  
    288.         canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);  
    289.   
    290.         canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);  
    291.   
    292.         Paint paint = new Paint();  
    293.         LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,  
    294.                 bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,  
    295.                 0x00ffffff, TileMode.CLAMP);  
    296.         paint.setShader(shader);  
    297.         // Set the Transfer mode to be porter duff and destination in  
    298.         paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));  
    299.         // Draw a rectangle using the paint with our linear gradient  
    300.         canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()  
    301.                 + reflectionGap, paint);  
    302.   
    303.         return bitmapWithReflection;  
    304.     }  
    305.   
    306. }  


     FileUtil

    [java] view plaincopy
    1. package com.wangge.coupon.util;  
    2.   
    3. import java.io.File;  
    4. import java.io.IOException;  
    5.   
    6. import android.os.Environment;  
    7. import android.util.Log;  
    8.   
    9. import com.wangge.coupon.http.AsynImageLoader;  
    10.   
    11. public class FileUtil {  
    12.     private static final String TAG = "FileUtil";  
    13.   
    14.     public static File getCacheFile(String imageUri){  
    15.         File cacheFile = null;  
    16.         try {  
    17.             if (Environment.getExternalStorageState().equals(  
    18.                     Environment.MEDIA_MOUNTED)) {  
    19.                 File sdCardDir = Environment.getExternalStorageDirectory();  
    20.                 String fileName = getFileName(imageUri);  
    21.                 File dir = new File(sdCardDir.getCanonicalPath()  
    22.                         + AsynImageLoader.CACHE_DIR);  
    23.                 if (!dir.exists()) {  
    24.                     dir.mkdirs();  
    25.                 }  
    26.                 cacheFile = new File(dir, fileName);  
    27.                 Log.i(TAG, "exists:" + cacheFile.exists() + ",dir:" + dir + ",file:" + fileName);  
    28.             }    
    29.         } catch (IOException e) {  
    30.             e.printStackTrace();  
    31.             Log.e(TAG, "getCacheFileError:" + e.getMessage());  
    32.         }  
    33.           
    34.         return cacheFile;  
    35.     }  
    36.       
    37.     public static String getFileName(String path) {  
    38.         int index = path.lastIndexOf("/");  
    39.         return path.substring(index + 1);  
    40.     }  
    41. }  

  • 相关阅读:
    【VS】解决Visual Studio无法登录的问题
    当vue 页面加载数据时显示 加载loading
    form 表单提交的另一种方式 js
    onclick="return doAlert()" onclick="return false"
    vue中sessionStorage的使用
    js把两个对象合并成一个对象
    Oracle 分页查询的一个实例
    oracle Group by 分组查询后,分页
    ProceedingJoinPoint获取当前方法
    Spring AOP无法拦截内部方法调用
  • 原文地址:https://www.cnblogs.com/dongdong230/p/4183148.html
Copyright © 2011-2022 走看看