码迷,mamicode.com
首页 > 移动开发 > 详细

Android中用双缓存技术,加载网络图片

时间:2016-08-19 20:50:40      阅读:433      评论:0      收藏:0      [点我收藏+]

标签:

最近在学校参加一个比赛,写的一个Android应用,里面要加载大量的网络图片,可是用传统的方法图片一多就会造成程序出现内存溢出而崩溃.因为自己也在学习中,所以看了很多博客和视频,然后参照这些大神的写源码,自己写了一个加载网络图片工具类.
里面要用到一个经典的图片缓存库DiskLruCache 下载地址为:  DiskLruCache下载

下面是使用这个类实现的 双缓存网络图片加载

  1. public class DiskLruCacheUtils {  
  2.     private static DiskLruCacheUtils diskLruCacheUtils;  
  3.   
  4.     private DiskLruCache diskLruCache; //LRU 磁盘缓存  
  5.     private LruCache<String, Bitmap> lruCache; //LRU 内存缓存  
  6.   
  7.     private Context context;  
  8.   
  9.     public DiskLruCacheUtils() {  
  10.     }  
  11.   
  12.     public static DiskLruCacheUtils getInstance() {  
  13.         if (diskLruCacheUtils == null) {  
  14.             diskLruCacheUtils = new DiskLruCacheUtils();  
  15.         }  
  16.         return diskLruCacheUtils;  
  17.     }  
  18.   
  19.   
  20.     public void open(Context context, String disk_cache_subdir, int disk_cache_size) {  
  21.         try {  
  22.             this.context = context;  
  23.   
  24.             // 获取到可用内存的最大值,使用内存超出这个值会引起OutOfMemory异常。  
  25.             // LruCache通过构造函数传入缓存值,以KB为单位。  
  26.             int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);  
  27.             // 使用最大可用内存值的1/8作为缓存的大小。  
  28.             int cacheSize = maxMemory / 8;  
  29.             lruCache = new LruCache<>(cacheSize);  
  30.   
  31.             /** 
  32.              * open()方法接受四个参数: 
  33.              * 第一个参数: 指定缓存地址 
  34.              * 第二个参数: 指定当前引用程序的版本号 
  35.              * 第三个参数: 指定同一个key可以对应多少个缓存文件,基本都是传1 
  36.              * 第四个参数: 指定最多可以缓存的字节数. 通常是10MB 
  37.              */  
  38.   
  39.             diskLruCache = DiskLruCache.open(getCacheDir(disk_cache_subdir), getAppVersion(), 1, disk_cache_size);  
  40.         } catch (IOException e) {  
  41.             e.printStackTrace();  
  42.         }  
  43.     }  
  44.   
  45.     /** 
  46.      * 获取磁盘缓存 
  47.      * @param url 
  48.      * @return 
  49.      */  
  50.     public InputStream getDiskCache(String url) {  
  51.         String key = hashkeyForDisk(url);  
  52.         try {  
  53.             DiskLruCache.Snapshot snapshot = diskLruCache.get(key);  
  54.             if (snapshot != null) {  
  55.                 return snapshot.getInputStream(0);  
  56.             }  
  57.         } catch (IOException e) {  
  58.             e.printStackTrace();  
  59.         }  
  60.         return null;  
  61.     }  
  62.   
  63.   
  64.     /** 
  65.      * 下载图片并缓存到内存和磁盘中 
  66.      * @param url 
  67.      * @param callBack 
  68.      */  
  69.     public void putCache(final String url, final CallBack callBack){  
  70.         new AsyncTask<String,Void,Bitmap>(){  
  71.   
  72.             @Override  
  73.             protected Bitmap doInBackground(String... params) {  
  74.                 String key = hashkeyForDisk(params[0]);  
  75. //                System.out.println("Key = "+key);  
  76.                 DiskLruCache.Editor editor = null;  
  77.                 Bitmap bitmap = null;  
  78.   
  79.                 URL url = null;  
  80.                 try {  
  81.                     url = new URL(params[0]);  
  82.                     HttpURLConnection conn = (HttpURLConnection) url.openConnection();  
  83.                     conn.setReadTimeout(30*1000);  
  84.                     conn.setConnectTimeout(30*1000);  
  85.                     ByteArrayOutputStream baos = null;  
  86.   
  87.                     if (conn.getResponseCode()==HttpURLConnection.HTTP_OK){  
  88.                         BufferedInputStream bis = new BufferedInputStream(conn.getInputStream());  
  89.                         baos = new ByteArrayOutputStream();  
  90.                         byte[] bytes = new byte[1024];  
  91.                         int len = -1;  
  92.                         while ((len = bis.read(bytes)) != -1) {  
  93.                             baos.write(bytes, 0, len);  
  94.                         }  
  95.   
  96.                         bis.close();  
  97.                         baos.close();  
  98.                         conn.disconnect();  
  99.                     }  
  100.                     if (baos !=null){  
  101.                         bitmap = decodeSampleadBitmapFromStream(baos.toByteArray(),300,300);  
  102. //                        bitmap = BitmapFactory.decodeByteArray(baos.toByteArray(),0,baos.toByteArray().length);  
  103.                         addBitmapToCache(params[0],bitmap); // 添加到内存缓存  
  104.                         editor = diskLruCache.edit(key); // 加入磁盘缓存  
  105. //                        System.out.println(url.getFile());  
  106.                         //位图压缩后输出(参数1: 压缩格式, 参数2: 质量(100 表示不压缩,30 表示压缩70%),参数3: 输出流)  
  107.                         bitmap.compress(Bitmap.CompressFormat.JPEG,30,editor.newOutputStream(0));  
  108.                         editor.commit();//提交  
  109.                     }  
  110.   
  111.   
  112.                 } catch (Exception e) {  
  113.                     try {  
  114.                         editor.abort();//放弃写入  
  115.                     } catch (IOException e1) {  
  116.                         e1.printStackTrace();  
  117.                     }  
  118.                     e.printStackTrace();  
  119.                 }  
  120.   
  121.   
  122.                 return bitmap;  
  123.             }  
  124.   
  125.             @Override  
  126.             protected void onPostExecute(Bitmap bitmap) {  
  127.                 super.onPostExecute(bitmap);  
  128.                 callBack.response(bitmap);  
  129.             }  
  130.         }.execute(url);  
  131.   
  132.     }  
  133.   
  134.     /** 
  135.      * 关闭磁盘缓存 
  136.      */  
  137.     public void close(){  
  138.         if (diskLruCache!=null&& !diskLruCache.isClosed()){  
  139.             try {  
  140.                 diskLruCache.close();  
  141.             } catch (IOException e) {  
  142.                 e.printStackTrace();  
  143.             }  
  144.         }  
  145.     }  
  146.   
  147.     /** 
  148.      * 刷新磁盘缓存 
  149.      */  
  150.     public void flush(){  
  151.         if (diskLruCache!=null){  
  152.             try {  
  153.                 diskLruCache.flush();  
  154.             } catch (IOException e) {  
  155.                 e.printStackTrace();  
  156.             }  
  157.         }  
  158.     }  
  159.   
  160.   
  161.     /** 
  162.      * 回调接口 
  163.      * @param <T> 
  164.      */  
  165.     public interface  CallBack<T>{  
  166.         public void response(T entity);  
  167.     }  
  168.   
  169.   
  170.     /** 
  171.      * 位图重新采样 
  172.      * 
  173.      * @param reqWidth  自定义的宽高 
  174.      * @param reqHeight 
  175.      * @return 
  176.      */  
  177.     public static Bitmap decodeSampleadBitmapFromStream(byte[] bytes, int reqWidth, int reqHeight) {  
  178.   
  179.         BitmapFactory.Options options = new BitmapFactory.Options();  
  180.         options.inJustDecodeBounds = true;//只解析边界,不加载到内存中  
  181.         BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);  
  182.         options.inSampleSize = calculatInSampleSize(options, reqWidth, reqHeight);//设置采样比为计算出的采样比例  
  183.         options.inJustDecodeBounds = false;  
  184.         return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);//重新解析图片  
  185.     }  
  186.   
  187.   
  188.     //添加缓存的对象  
  189.     public  void addBitmapToCache(String url,Bitmap bitmap){  
  190.         String key = hashkeyForDisk(url);  
  191.         if (getBitmapFromMenCache(key)==null){  
  192.             lruCache.put(key,bitmap);  
  193.         }  
  194.     }  
  195.   
  196.     //从缓存中获取对象  
  197.     public  Bitmap getBitmapFromMenCache(String url){  
  198.         String key = hashkeyForDisk(url);  
  199.         return  lruCache.get(key);  
  200.     }  
  201.   
  202.   
  203.     /** 
  204.      * 计算位图的采样比例大小 
  205.      * 
  206.      * @param options 
  207.      * @param reqWidth  需要的宽高 
  208.      * @param reqHeight 
  209.      * @return 
  210.      */  
  211.     private static int calculatInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {  
  212.         //获取位图的原宽高  
  213.         final int w = options.outWidth;  
  214.         final int h = options.outHeight;  
  215.         int inSampleSize = 1;  
  216.         //如果原图的宽高比需要的图片宽高大  
  217.         if (w > reqWidth || h > reqHeight) {  
  218.             if (w > h) {  
  219.                 inSampleSize = Math.round((float) h / (float) reqHeight);  
  220.             } else {  
  221.                 inSampleSize = Math.round((float) w / (float) reqWidth);  
  222.             }  
  223.         }  
  224.         return inSampleSize;  
  225.     }  
  226.   
  227.   
  228.     /** 
  229.      * MD5加密计算 
  230.      * 
  231.      * @param key 
  232.      * @return 
  233.      */  
  234.     private String hashkeyForDisk(String key) {  
  235.         String cachekey;  
  236.   
  237.         try {  
  238.             final MessageDigest mDigest = MessageDigest.getInstance("MD5");  
  239.             mDigest.update(key.getBytes());  
  240.             cachekey = bytesToHexString(mDigest.digest());  
  241.         } catch (NoSuchAlgorithmException e) {  
  242.             cachekey = String.valueOf(key.hashCode());  
  243.         }  
  244.   
  245.         return cachekey;  
  246.     }  
  247.   
  248.     private String bytesToHexString(byte[] bytes) {  
  249.         StringBuilder sb = new StringBuilder();  
  250.         for (int i = 0; i < bytes.length; i++) {  
  251.             String hex = Integer.toHexString(0xff & bytes[i]);  
  252.             if (hex.length() == 1) {  
  253.                 sb.append(0);  
  254.             }  
  255.             sb.append(hex);  
  256.         }  
  257.         return sb.toString();  
  258.     }  
  259.   
  260.   
  261.     /** 
  262.      * 获取缓存的地址 
  263.      * 
  264.      * @param name 
  265.      * @return 
  266.      */  
  267.     private File getCacheDir(String name) {  
  268.         String cachePath = Environment.getExternalStorageState()  
  269.                 == Environment.MEDIA_MOUNTED || !Environment.isExternalStorageRemovable() ?  
  270.                 context.getExternalCacheDir().getPath() : context.getCacheDir().getPath();  
  271.   
  272.         return new File(cachePath + File.separator + name);  
  273.     }  
  274.   
  275.     /** 
  276.      * 获取App的版本号 
  277.      * 
  278.      * @return 
  279.      */  
  280.     private int getAppVersion() {  
  281.         try {  
  282.             return context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;  
  283.         } catch (PackageManager.NameNotFoundException e) {  
  284.             e.printStackTrace();  
  285.         }  
  286.         return 1;  
  287.     }  
  288. }  

decodeSampleadBitmapFromStream(byte[] bytes, int reqWidth, int reqHeight)这个函数的实现可以参照 郭大神的博客:Android高效加载大图、多图方案,有效避免程序OOM

自己也是小白,好多都是复制粘贴,嘿嘿 !  这里就不进行代码的分析了(其实好多我也不懂...),下面就自己上demo把:

现将上面的DiskLruCache, 在项目中创建一个libcore.io包,将这.jar文件复制进去,然后实现上边的代码(有点多哈!直接复制过去把!). 我这里直接创建了一个DiskLruCacheUtils类里面就是上面的代码! 还是截个图:↓↓↓↓
技术分享

技术分享技术分享
使用这个工具类的方法:
在你需要的使用这类的Activity 或fragment中,首先:

  1. private DiskLruCacheUtils diskLruCacheUtils;//创建对象  
  2. private static final String DISK_CACHE_SUBDIR = "temp"; //设置图片缓存的文件  
  3. private static final int DISK_CACHE_SIZE= 100*1024*1024; // 设置SD卡缓存的大小  

然后在他们的声明周期中:
  1. @Override  
  2.     protected void onResume() {  
  3.         super.onResume();  
  4.         diskLruCacheUtils = DiskLruCacheUtils.getInstance();  
  5.         diskLruCacheUtils.open(this,DISK_CACHE_SUBDIR,DISK_CACHE_SIZE);//打开缓存  
  6.     }  
  7.   
  8.     @Override  
  9.     protected void onPause() {  
  10.         super.onPause();  
  11.         diskLruCacheUtils.flush(); //刷新缓存  
  12.     }  
  13.   
  14.     @Override  
  15.     protected void onStop() {  
  16.         super.onStop();  
  17.         diskLruCacheUtils.close(); //关闭缓存  
  18.     }  

加了这代码就可以真正的使用这个工具类了.
但是这样还不行,还得写个图片加载方法:

  1. private void loadBitmap(String url, final ImageView imageView) {  
  2.         if (imageView.getTag().equals(url)) {  
  3.             //从内存缓存中取图片  
  4.             Bitmap bitmap = diskLruCacheUtils.getBitmapFromMenCache(url);  
  5.             if (bitmap == null) {  
  6.                 //如果内存中为空 从磁盘缓存中取  
  7.                 InputStream in = diskLruCacheUtils.getDiskCache(url);  
  8.   
  9.                 if (in == null) {  
  10.                     //如果缓存中都为空,就通过网络加载,并加入缓存  
  11.                     diskLruCacheUtils.putCache(url, new DiskLruCacheUtils.CallBack<Bitmap>() {  
  12.                         @Override  
  13.                         public void response(Bitmap entity) {  
  14. //                            System.out.println("网络中下载...");  
  15.                             imageView.setImageBitmap(entity);  
  16.                         }  
  17.                     });  
  18.                 } else {  
  19.                     System.out.println("磁盘中取出...");  
  20.                     bitmap = BitmapFactory.decodeStream(in);  
  21.                     diskLruCacheUtils.addBitmapToCache(url, bitmap);  
  22.                     imageView.setImageBitmap(bitmap);  
  23.                 }  
  24.             } else {  
  25. //                System.out.println("内存中取出...");  
  26.                 imageView.setImageBitmap(bitmap);  
  27.             }  
  28.         }  
  29.     }  

然后在你需要加载图片的地方使用该方法就OK, 看起复杂其实还挺简单的  ...(复制过去不就行了...)

直接上Demo:
这是activity_main.xml文件

下面上布局文件 挺简单的 RecyclerView+CardView:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:paddingBottom="@dimen/activity_vertical_margin"  
  7.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  8.     android:paddingRight="@dimen/activity_horizontal_margin"  
  9.     android:paddingTop="@dimen/activity_vertical_margin"  
  10.     tools:context="zhengliang.com.bitmaplrucache.MainActivity">  
  11.   
  12.     <android.support.v7.widget.RecyclerView  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="match_parent"  
  15.         android:id="@+id/rlv_list"  
  16.         >  
  17.     </android.support.v7.widget.RecyclerView>  
  18. </RelativeLayout>  

挺简单的就一个 RecyclerView 因为要加载很多图片所以就用这个了,(哈哈! 我喜欢他的瀑布流! 爽到爆炸啊...)


这是item.xml文件

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:layout_width="wrap_content"  
  5.     android:layout_height="wrap_content"  
  6.     android:layout_margin="2dp"  
  7.     app:cardBackgroundColor="@color/colorAccent"  
  8.     app:cardCornerRadius="2dp"  
  9.     android:background="@color/colorAccent"  
  10.     >  
  11.   
  12.     <ImageView  
  13.         android:id="@+id/pic"  
  14.         android:layout_width="match_parent"  
  15.         android:layout_height="wrap_content"  
  16.         android:scaleType="centerCrop"  
  17.         />  
  18.   
  19. </android.support.v7.widget.CardView>  

就一个CardView ,里面放了一个ImageView 

MainActivity类中代码如下:
      因为这里没有图片资源所以自己用Volley框架写了一个获取图片资源的getImageUrl()方法里面返回一些图片资源的URL地址  (找图片真的很恼火啊,一条一条的把图片地址复制过来不是我的风范啊! 就在百度图片中经过千辛万苦扒了个图片API接口下来,哈哈 有图片咯!)


  1. <pre name="code" class="java">public class MainActivity extends AppCompatActivity{  
  2.   
  3.   
  4.     private List<String> data;  
  5.     private DiskLruCacheUtils diskLruCacheUtils;  
  6.     private static final String DISK_CACHE_SUBDIR = "temp";  
  7.     private static final int DISK_CACHE_SIZE= 100*1024*1024;  
  8.     private RecyclerView rlvlist;  
  9.   
  10.     private MyAdapter myAdapter;  
  11.   
  12.   
  13.     @Override  
  14.     protected void onCreate(Bundle savedInstanceState) {  
  15.         super.onCreate(savedInstanceState);  
  16.         setContentView(R.layout.activity_main);  
  17.         initViews();  
  18.         getImageUrl("http://image.baidu.com/channel/listjson?pn=0&rn=200&tag1=美女&tag2=小清新&ie=utf8");  
  19.     }  
  20.   
  21.   
  22.     private void initViews() {  
  23.         data = new ArrayList<String>();  
  24.         this.rlvlist = (RecyclerView) findViewById(R.id.rlv_list);  
  25.         rlvlist.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));  
  26.     }  
  27.   
  28.     @Override  
  29.     protected void onResume() {  
  30.         super.onResume();  
  31.         diskLruCacheUtils = DiskLruCacheUtils.getInstance();  
  32.         diskLruCacheUtils.open(this,DISK_CACHE_SUBDIR,DISK_CACHE_SIZE);  
  33.     }  
  34.   
  35.     @Override  
  36.     protected void onPause() {  
  37.         super.onPause();  
  38.         diskLruCacheUtils.flush();  
  39.     }  
  40.   
  41.     @Override  
  42.     protected void onStop() {  
  43.         super.onStop();  
  44.         diskLruCacheUtils.close();  
  45.     }  
  46.   
  47.     public void getImageUrl(String url){  
  48.   
  49.         final RequestQueue mQueue = Volley.newRequestQueue(this);  
  50.   
  51.         JsonObjectRequest stringRequest = new JsonObjectRequest(url, null,  
  52.                 new Response.Listener<JSONObject>() {  
  53.                     @Override  
  54.                     public void onResponse(JSONObject jsonObject) {  
  55. //                        System.out.println(jsonObject);  
  56.                         try {  
  57.                             JSONArray jsonArray = jsonObject.getJSONArray("data");  
  58.                             for (int i = 0; i <jsonArray.length() ; i++) {  
  59.                                 JSONObject item = jsonArray.getJSONObject(i);  
  60.                                 String url = item.getString("image_url");  
  61.                                 String name = item.getString("tags");  
  62.                                 data.add(url);  
  63.   
  64.                                 myAdapter = new MyAdapter(data,MainActivity.this,diskLruCacheUtils);  
  65.                                 rlvlist.setAdapter(myAdapter);  
  66.                                 myAdapter.notifyDataSetChanged();  
  67.                             }  
  68.                         } catch (JSONException e) {  
  69.                             e.printStackTrace();  
  70.                         }  
  71.                     }  
  72.                 }, new Response.ErrorListener() {  
  73.             @Override  
  74.             public void onErrorResponse(VolleyError volleyError) {  
  75.   
  76.             }  
  77.         }  
  78.         );  
  79.   
  80.         mQueue.add(stringRequest);  
  81.   
  82.         if (data.size()==200){  
  83.             getImageUrl("http://image.baidu.com/channel/listjson?pn=0&rn=200&tag1=美女&tag2=全部&ie=utf8");  
  84.         }  
  85.   
  86.     }  
  87.     public void getImageUrl2(String url){  
  88.   
  89.         final RequestQueue mQueue = Volley.newRequestQueue(this);  
  90.   
  91.         JsonObjectRequest stringRequest = new JsonObjectRequest(url, null,  
  92.                 new Response.Listener<JSONObject>() {  
  93.                     @Override  
  94.                     public void onResponse(JSONObject jsonObject) {  
  95. //                        System.out.println(jsonObject);  
  96.                         try {  
  97.                             JSONArray jsonArray = jsonObject.getJSONArray("imgs");  
  98.                             for (int i = 0; i <jsonArray.length() ; i++) {  
  99.                                 JSONObject item = jsonArray.getJSONObject(i);  
  100.                                 String url = item.getString("hoverURL");  
  101.                                 String name = item.getString("fromPageTitle");  
  102.                                 data.add(url);  
  103.   
  104.                                 myAdapter = new MyAdapter(data,MainActivity.this,diskLruCacheUtils);  
  105.                                 rlvlist.setAdapter(myAdapter);  
  106.                                 myAdapter.notifyDataSetChanged();  
  107.                             }  
  108.                         } catch (JSONException e) {  
  109.                             e.printStackTrace();  
  110.                         }  
  111.                     }  
  112.                 }, new Response.ErrorListener() {  
  113.             @Override  
  114.             public void onErrorResponse(VolleyError volleyError) {  
  115.   
  116.             }  
  117.         }  
  118.         );  
  119.   
  120.         mQueue.add(stringRequest);  
  121.   
  122.   
  123.     }  
  124.   
  125.   
  126.   
  127. }  


   然后是就是实现RecyclerView 的Adapter,因为网络图片的加载都要在Adapter中,所以loadBitmap()方法我就直接写在这里了  废话少说直接上代码

  1. public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {  
  2.   
  3.     private List<String> list;  
  4.     private Context context;  
  5.     private DiskLruCacheUtils diskLruCacheUtils;  
  6.   
  7.     public MyAdapter(List<String> list, Context context, DiskLruCacheUtils diskLruCacheUtils) {  
  8.         this.list = list;  
  9.         this.context = context;  
  10.         this.diskLruCacheUtils = diskLruCacheUtils;  
  11.     }  
  12.   
  13.     @Override  
  14.     public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  15.   
  16.         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view,parent,false);  
  17.         return new ViewHolder(view);  
  18.     }  
  19.   
  20.     @Override  
  21.     public void onBindViewHolder(ViewHolder holder, int position) {  
  22.         holder.pic.setTag(list.get(position));  
  23.         loadBitmap(list.get(position),holder.pic);  
  24.         System.out.println(position);  
  25.     }  
  26.   
  27.     @Override  
  28.     public int getItemCount() {  
  29.         return list==null?0:list.size();  
  30.     }  
  31.   
  32.     public static class ViewHolder extends RecyclerView.ViewHolder {  
  33.   
  34.         public ImageView pic;  
  35.   
  36.         public ViewHolder(View itemView) {  
  37.             super(itemView);  
  38.             pic = (ImageView) itemView.findViewById(R.id.pic);  
  39.   
  40.         }  
  41.     }  
  42.   
  43.     private void loadBitmap(String url, final ImageView imageView) {  
  44.         if (imageView.getTag().equals(url)) {  
  45.             //从内存缓存中取图片  
  46.             Bitmap bitmap = diskLruCacheUtils.getBitmapFromMenCache(url);  
  47.             if (bitmap == null) {  
  48.                 //如果内存中为空 从磁盘缓存中取  
  49.                 InputStream in = diskLruCacheUtils.getDiskCache(url);  
  50.   
  51.                 if (in == null) {  
  52.                     //如果缓存中都为空,就通过网络加载,并加入缓存  
  53.                     diskLruCacheUtils.putCache(url, new DiskLruCacheUtils.CallBack<Bitmap>() {  
  54.                         @Override  
  55.                         public void response(Bitmap entity) {  
  56. //                            System.out.println("网络中下载...");  
  57.                             imageView.setImageBitmap(entity);  
  58.                         }  
  59.                     });  
  60.                 } else {  
  61.                     System.out.println("磁盘中取出...");  
  62.                     bitmap = BitmapFactory.decodeStream(in);  
  63.                     diskLruCacheUtils.addBitmapToCache(url, bitmap);  
  64.                     imageView.setImageBitmap(bitmap);  
  65.                 }  
  66.             } else {  
  67. //                System.out.println("内存中取出...");  
  68.                 imageView.setImageBitmap(bitmap);  
  69.             }  
  70.         }  
  71.     }  
  72.   
  73. }  


大工告成 看看效果

技术分享技术分享

     第一进入时全是从 显示"网络中下载..."  因为RecyclerView和ListView一样,超出屏幕的Item都会被回收,当再次滑动回到上次的位置就会重新获取item,并且会重新获取图片,.
   下面看看滑动回去打印的log 

技术分享技术分享

      全是显示从内存中取出,并没有再重网络中下载,说明刚才的图片都缓存到内存中了,这样就加快的图片的显示,还节省了流量!(这年头流量伤不起啊!)
下面再看看关闭应用再打开是什么效果吧!

技术分享技术分享

        全部显示的是从磁盘中取出... 因为关闭应用,这个时候内存中缓存的图片就会被清空. 这个时候就会自动看SD中是否有缓存了. 并且从SD中取出的图片会再一次缓存到内存中去...我这里是加载的200张图片,完全没有问题,嘿嘿...

Android中用双缓存技术,加载网络图片

标签:

原文地址:http://www.cnblogs.com/yukewei/p/5788852.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!