zoukankan      html  css  js  c++  java
  • LruCache为GridView异步加载大量网络图片

    MainActivity如下:

    1. import android.os.Bundle;  
    2. import android.widget.GridView;  
    3. import android.app.Activity;  
    4. /** 
    5.  * Demo描述: 
    6.  * 在GridView中采用LruCache异步加载大量图片,避免OOM 
    7.  *  
    8.  * 学习资料: 
    9.  * http://blog.csdn.net/guolin_blog/article/details/9526203 
    10.  * Thank you very much 
    11.  */  
    12.   
    13. public class MainActivity extends Activity {  
    14.     private GridView mGridView;  
    15.     private GridViewAdapter mGridViewAdapter;  
    16.     @Override  
    17.     protected void onCreate(Bundle savedInstanceState) {  
    18.         super.onCreate(savedInstanceState);  
    19.         setContentView(R.layout.main);  
    20.         init();  
    21.     }  
    22.       
    23.     private void init(){  
    24.         mGridView = (GridView) findViewById(R.id.gridView);  
    25.         mGridViewAdapter = new GridViewAdapter(this, 0, ImagesUrl.Urls, mGridView);  
    26.         mGridView.setAdapter(mGridViewAdapter);  
    27.     }  
    28.   
    29.     //取消所有的下载任务  
    30.     @Override  
    31.     protected void onDestroy() {  
    32.         super.onDestroy();  
    33.         mGridViewAdapter.cancelAllTasks();  
    34.     }  

    GridViewAdapter如下:

    1. import java.net.HttpURLConnection;  
    2. import java.net.URL;  
    3. import java.util.HashSet;  
    4. import android.annotation.SuppressLint;  
    5. import android.content.Context;  
    6. import android.graphics.Bitmap;  
    7. import android.graphics.BitmapFactory;  
    8. import android.os.AsyncTask;  
    9. import android.support.v4.util.LruCache;  
    10. import android.view.LayoutInflater;  
    11. import android.view.View;  
    12. import android.view.ViewGroup;  
    13. import android.widget.AbsListView;  
    14. import android.widget.AbsListView.OnScrollListener;  
    15. import android.widget.ArrayAdapter;  
    16. import android.widget.GridView;  
    17. import android.widget.ImageView;  
    18. /** 
    19.  * LruCache的流程分析: 
    20.  * 我们从第一次进入应用的情况下开始 
    21.  * 1 依据图片的Url从LruCache缓存中取图片. 
    22.  *   若图片存在缓存中,则显示该图片;否则显示默认图片 
    23.  * 2 因为是第一次进入该界面所以会执行: 
    24.  *   loadBitmaps(firstVisibleItem, visibleItemCount); 
    25.  *   我们从loadBitmaps()方法作为切入点,继续往下梳理 
    26.  * 3 尝试从LruCache缓存中取图片.如果在显示即可,否则进入4 
    27.  * 4 开启一个异步任务下载图片.下载完成后显示图片,并且将 
    28.  *   该图片存入LruCache缓存中 
    29.  *    
    30.  * 在停止滑动时,会调用loadBitmaps(firstVisibleItem, visibleItemCount) 
    31.  * 情况与上类似 
    32.  */  
    33. @SuppressLint("NewApi")  
    34. public class GridViewAdapter extends ArrayAdapter<String> {  
    35.       
    36.     private GridView mGridView;  
    37.     //图片缓存类  
    38.     private LruCache<String, Bitmap> mLruCache;  
    39.     //记录所有正在下载或等待下载的任务  
    40.     private HashSet<DownloadBitmapAsyncTask> mDownloadBitmapAsyncTaskHashSet;  
    41.     //GridView中可见的第一张图片的下标  
    42.     private int mFirstVisibleItem;  
    43.     //GridView中可见的图片的数量  
    44.     private int mVisibleItemCount;  
    45.     //记录是否是第一次进入该界面  
    46.     private boolean isFirstEnterThisActivity = true;  
    47.   
    48.     public GridViewAdapter(Context context, int textViewResourceId,String[] objects, GridView gridView) {  
    49.         super(context, textViewResourceId, objects);  
    50.           
    51.         mGridView = gridView;  
    52.         mGridView.setOnScrollListener(new ScrollListenerImpl());  
    53.           
    54.         mDownloadBitmapAsyncTaskHashSet = new HashSet<DownloadBitmapAsyncTask>();  
    55.           
    56.         // 获取应用程序最大可用内存  
    57.         int maxMemory = (int) Runtime.getRuntime().maxMemory();  
    58.         // 设置图片缓存大小为maxMemory的1/6  
    59.         int cacheSize = maxMemory/6;  
    60.           
    61.         mLruCache = new LruCache<String, Bitmap>(cacheSize) {  
    62.             @Override  
    63.             protected int sizeOf(String key, Bitmap bitmap) {  
    64.                 return bitmap.getByteCount();  
    65.             }  
    66.         };  
    67.           
    68.     }  
    69.   
    70.     @Override  
    71.     public View getView(int position, View convertView, ViewGroup parent) {  
    72.         String url = getItem(position);  
    73.         View view;  
    74.         if (convertView == null) {  
    75.             view = LayoutInflater.from(getContext()).inflate(R.layout.gridview_item, null);  
    76.         } else {  
    77.             view = convertView;  
    78.         }  
    79.         ImageView imageView = (ImageView) view.findViewById(R.id.imageView);  
    80.         //为该ImageView设置一个Tag,防止图片错位  
    81.         imageView.setTag(url);  
    82.         //为该ImageView设置显示的图片  
    83.         setImageForImageView(url, imageView);  
    84.         return view;  
    85.     }  
    86.   
    87.     /** 
    88.      * 为ImageView设置图片(Image) 
    89.      * 1 从缓存中获取图片 
    90.      * 2 若图片不在缓存中则为其设置默认图片 
    91.      */  
    92.     private void setImageForImageView(String imageUrl, ImageView imageView) {  
    93.         Bitmap bitmap = getBitmapFromLruCache(imageUrl);  
    94.         if (bitmap != null) {  
    95.             imageView.setImageBitmap(bitmap);  
    96.         } else {  
    97.             imageView.setImageResource(R.drawable.default_image);  
    98.         }  
    99.     }  
    100.   
    101.     /** 
    102.      * 将图片存储到LruCache 
    103.      */  
    104.     public void addBitmapToLruCache(String key, Bitmap bitmap) {  
    105.         if (getBitmapFromLruCache(key) == null) {  
    106.             mLruCache.put(key, bitmap);  
    107.         }  
    108.     }  
    109.   
    110.     /** 
    111.      * 从LruCache缓存获取图片 
    112.      */  
    113.     public Bitmap getBitmapFromLruCache(String key) {  
    114.         return mLruCache.get(key);  
    115.     }  
    116.   
    117.       
    118.   
    119.    /** 
    120.     * 为GridView的item加载图片 
    121.     *  
    122.     * @param firstVisibleItem  
    123.     * GridView中可见的第一张图片的下标 
    124.     *  
    125.     * @param visibleItemCount  
    126.     * GridView中可见的图片的数量 
    127.     *  
    128.     */  
    129.     private void loadBitmaps(int firstVisibleItem, int visibleItemCount) {  
    130.         try {  
    131.             for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) {  
    132.                 String imageUrl = ImagesUrl.Urls[i];  
    133.                 Bitmap bitmap = getBitmapFromLruCache(imageUrl);  
    134.                 if (bitmap == null) {  
    135.                     DownloadBitmapAsyncTask downloadBitmapAsyncTask = new DownloadBitmapAsyncTask();  
    136.                     mDownloadBitmapAsyncTaskHashSet.add(downloadBitmapAsyncTask);  
    137.                     downloadBitmapAsyncTask.execute(imageUrl);  
    138.                 } else {  
    139.                     //依据Tag找到对应的ImageView显示图片  
    140.                     ImageView imageView = (ImageView) mGridView.findViewWithTag(imageUrl);  
    141.                     if (imageView != null && bitmap != null) {  
    142.                         imageView.setImageBitmap(bitmap);  
    143.                     }  
    144.                 }  
    145.             }  
    146.         } catch (Exception e) {  
    147.             e.printStackTrace();  
    148.         }  
    149.     }  
    150.   
    151.     /** 
    152.      * 取消所有正在下载或等待下载的任务 
    153.      */  
    154.     public void cancelAllTasks() {  
    155.         if (mDownloadBitmapAsyncTaskHashSet != null) {  
    156.             for (DownloadBitmapAsyncTask task : mDownloadBitmapAsyncTaskHashSet) {  
    157.                 task.cancel(false);  
    158.             }  
    159.         }  
    160.     }  
    161.       
    162.       
    163.     private class ScrollListenerImpl implements OnScrollListener{  
    164.         /** 
    165.          *  
    166.          * 我们的本意是通过onScrollStateChanged获知:每次GridView停止滑动时加载图片 
    167.          * 但是存在一个特殊情况: 
    168.          * 当第一次入应用的时候,此时并没有滑动屏幕的操作即不会调用onScrollStateChanged,但应该加载图片. 
    169.          * 所以在此处做一个特殊的处理. 
    170.          * 即代码: 
    171.          * if (isFirstEnterThisActivity && visibleItemCount > 0) { 
    172.          *      loadBitmaps(firstVisibleItem, visibleItemCount); 
    173.          *      isFirstEnterThisActivity = false; 
    174.          *    } 
    175.          *     
    176.          * ------------------------------------------------------------ 
    177.          *  
    178.          * 其余的都是正常情况. 
    179.          * 所以我们需要不断保存:firstVisibleItem和visibleItemCount 
    180.          * 从而便于中在onScrollStateChanged()判断当停止滑动时加载图片 
    181.          *  
    182.          */  
    183.         @Override  
    184.         public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {  
    185.             mFirstVisibleItem = firstVisibleItem;  
    186.             mVisibleItemCount = visibleItemCount;  
    187.             if (isFirstEnterThisActivity && visibleItemCount > 0) {  
    188.                 loadBitmaps(firstVisibleItem, visibleItemCount);  
    189.                 isFirstEnterThisActivity = false;  
    190.             }  
    191.         }  
    192.           
    193.         /** 
    194.          *  GridView停止滑动时下载图片 
    195.          *  其余情况下取消所有正在下载或者等待下载的任务 
    196.          */  
    197.         @Override  
    198.         public void onScrollStateChanged(AbsListView view, int scrollState) {  
    199.             if (scrollState == SCROLL_STATE_IDLE) {  
    200.                 loadBitmaps(mFirstVisibleItem, mVisibleItemCount);  
    201.             } else {  
    202.                 cancelAllTasks();  
    203.             }  
    204.         }  
    205.           
    206.     }  
    207.   
    208.     /** 
    209.      * 下载图片的异步任务 
    210.      */  
    211.     class DownloadBitmapAsyncTask extends AsyncTask<String, Void, Bitmap> {  
    212.         private String imageUrl;  
    213.         @Override  
    214.         protected Bitmap doInBackground(String... params) {  
    215.             imageUrl = params[0];  
    216.             Bitmap bitmap = downloadBitmap(params[0]);  
    217.             if (bitmap != null) {  
    218.                 //下载完后,将其缓存到LrcCache  
    219.                 addBitmapToLruCache(params[0], bitmap);  
    220.             }  
    221.             return bitmap;  
    222.         }  
    223.   
    224.         @Override  
    225.         protected void onPostExecute(Bitmap bitmap) {  
    226.             super.onPostExecute(bitmap);  
    227.             //下载完成后,找到其对应的ImageView显示图片  
    228.             ImageView imageView = (ImageView) mGridView.findViewWithTag(imageUrl);  
    229.             if (imageView != null && bitmap != null) {  
    230.                 imageView.setImageBitmap(bitmap);  
    231.             }  
    232.             mDownloadBitmapAsyncTaskHashSet.remove(this);  
    233.         }  
    234.     }  
    235.   
    236.     // 获取Bitmap  
    237.     private Bitmap downloadBitmap(String imageUrl) {  
    238.         Bitmap bitmap = null;  
    239.         HttpURLConnection httpURLConnection = null;  
    240.         try {  
    241.             URL url = new URL(imageUrl);  
    242.             httpURLConnection = (HttpURLConnection) url.openConnection();  
    243.             httpURLConnection.setConnectTimeout(5 * 1000);  
    244.             httpURLConnection.setReadTimeout(10 * 1000);  
    245.             httpURLConnection.setDoInput(true);  
    246.             httpURLConnection.setDoOutput(true);  
    247.             bitmap = BitmapFactory.decodeStream(httpURLConnection.getInputStream());  
    248.         } catch (Exception e) {  
    249.             e.printStackTrace();  
    250.         } finally {  
    251.             if (httpURLConnection != null) {  
    252.                 httpURLConnection.disconnect();  
    253.             }  
    254.         }  
    255.         return bitmap;  
    256.     }  
    257.   
    258. }  

    ImagesUrl如下:

    1. public class ImagesUrl {  
    2.   
    3.     public final static String[] Urls = new String[] {  
    4.             "https://lh6.googleusercontent.com/-55osAWw3x0Q/URquUtcFr5I/AAAAAAAAAbs/rWlj1RUKrYI/s160-c/A%252520Photographer.jpg",  
    5.             "https://lh4.googleusercontent.com/--dq8niRp7W4/URquVgmXvgI/AAAAAAAAAbs/-gnuLQfNnBA/s160-c/A%252520Song%252520of%252520Ice%252520and%252520Fire.jpg",  
    6.             "https://lh5.googleusercontent.com/-7qZeDtRKFKc/URquWZT1gOI/AAAAAAAAAbs/hqWgteyNXsg/s160-c/Another%252520Rockaway%252520Sunset.jpg",  
    7.             "https://lh3.googleusercontent.com/--L0Km39l5J8/URquXHGcdNI/AAAAAAAAAbs/3ZrSJNrSomQ/s160-c/Antelope%252520Butte.jpg",  
    8.             "https://lh6.googleusercontent.com/-8HO-4vIFnlw/URquZnsFgtI/AAAAAAAAAbs/WT8jViTF7vw/s160-c/Antelope%252520Hallway.jpg",  
    9.             "https://lh4.googleusercontent.com/-WIuWgVcU3Qw/URqubRVcj4I/AAAAAAAAAbs/YvbwgGjwdIQ/s160-c/Antelope%252520Walls.jpg",  
    10.             "https://lh6.googleusercontent.com/-UBmLbPELvoQ/URqucCdv0kI/AAAAAAAAAbs/IdNhr2VQoQs/s160-c/Apre%2525CC%252580s%252520la%252520Pluie.jpg"};

  • 相关阅读:
    第二阶段团队冲刺第五天
    第二阶段冲刺七
    第二阶段冲刺六
    第二阶段冲刺五
    第二阶段冲刺四
    冲刺第二阶段三
    冲刺第二阶段二
    冲刺第二阶段 一
    项目总结
    第二阶段SCRUM
  • 原文地址:https://www.cnblogs.com/yiweiaimeng/p/4969387.html
Copyright © 2011-2022 走看看