android点滴(22)之图片懒加载


  1 package com.fedorvlasov.lazylist;

 2 
 3 import java.io.File;
 4 import android.content.Context;
 5 
 6 public class FileCache {
 7     
 8     private File cacheDir;
 9     
10     public FileCache(Context context){
11         //Find the dir to save cached images
12         if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
13             cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"LazyList");
14         else
15             cacheDir=context.getCacheDir();
16         if(!cacheDir.exists())
17             cacheDir.mkdirs();
18     }
19     
20     public File getFile(String url){
21         //I identify images by hashcode. Not a perfect solution, good for the demo.
22         String filename=String.valueOf(url.hashCode());
23         //Another possible solution (thanks to grantland)
24         //String filename = URLEncoder.encode(url);
25         File f = new File(cacheDir, filename);
26         return f;
27         
28     }
29     
30     public void clear(){
31         File[] files=cacheDir.listFiles();
32         if(files==null)
33             return;
34         for(File f:files)
35             f.delete();
36     }
37 
38 }

 

  1 package com.fedorvlasov.lazylist;

 2 
 3 import java.util.Collections;
 4 import java.util.Iterator;
 5 import java.util.LinkedHashMap;
 6 import java.util.Map;
 7 import java.util.Map.Entry;
 8 import android.graphics.Bitmap;
 9 import android.util.Log;
10 
11 public class MemoryCache {
12 
13     private static final String TAG = "MemoryCache";
14     private Map<String, Bitmap> cache=Collections.synchronizedMap(
15             new LinkedHashMap<String, Bitmap>(10,1.5f,true));//Last argument true for LRU ordering
16     private long size=0;//current allocated size
17     private long limit=1000000;//max memory in bytes
18 
19     public MemoryCache(){
20         //use 25% of available heap size
21         setLimit(Runtime.getRuntime().maxMemory()/4);
22     }
23     
24     public void setLimit(long new_limit){
25         limit=new_limit;
26         Log.i(TAG, "MemoryCache will use up to "+limit/1024./1024.+"MB");
27     }
28 
29     public Bitmap get(String id){
30         if(!cache.containsKey(id))
31             return null;
32         return cache.get(id);
33     }
34 
35     public void put(String id, Bitmap bitmap){
36         try{
37             if(cache.containsKey(id))
38                 size-=getSizeInBytes(cache.get(id));
39             cache.put(id, bitmap);
40             size+=getSizeInBytes(bitmap);
41             checkSize();
42         }catch(Throwable th){
43             th.printStackTrace();
44         }
45     }
46 
47     private void checkSize() {
48         Log.i(TAG, "cache size="+size+" length="+cache.size());
49         if(size>limit){
50             Iterator<Entry<String, Bitmap>> iter=cache.entrySet().iterator();//least recently accessed item will be the first one iterated  
51             while(iter.hasNext()){
52                 Entry<String, Bitmap> entry=iter.next();
53                 size-=getSizeInBytes(entry.getValue());
54                 iter.remove();
55                 if(size<=limit)
56                     break;
57             }
58             Log.i(TAG, "Clean cache. New size "+cache.size());
59         }
60     }
61 
62     public void clear() {
63         cache.clear();
64     }
65 
66     long getSizeInBytes(Bitmap bitmap) {
67         if(bitmap==null)
68             return 0;
69         return bitmap.getRowBytes() * bitmap.getHeight();
70     }
71 }

 

  1 package com.fedorvlasov.lazylist;

 2 
 3 import java.io.InputStream;
 4 import java.io.OutputStream;
 5 
 6 public class Utils {
 7     public static void CopyStream(InputStream is, OutputStream os)
 8     {
 9         final int buffer_size=1024;
10         try
11         {
12             byte[] bytes=new byte[buffer_size];
13             for(;;)
14             {
15               int count=is.read(bytes, 0, buffer_size);
16               if(count==-1)
17                   break;
18               os.write(bytes, 0, count);
19             }
20         }
21         catch(Exception ex){}
22     }
23 }

 

   1 package com.fedorvlasov.lazylist;

  2 
  3 import java.io.File;
  4 import java.io.FileInputStream;
  5 import java.io.FileNotFoundException;
  6 import java.io.FileOutputStream;
  7 import java.io.InputStream;
  8 import java.io.OutputStream;
  9 import java.net.HttpURLConnection;
 10 import java.net.URL;
 11 import java.util.Collections;
 12 import java.util.Map;
 13 import java.util.WeakHashMap;
 14 import java.util.concurrent.ExecutorService;
 15 import java.util.concurrent.Executors;
 16 
 17 import android.app.Activity;
 18 import android.content.Context;
 19 import android.graphics.Bitmap;
 20 import android.graphics.BitmapFactory;
 21 import android.widget.ImageView;
 22 
 23 public class ImageLoader {
 24     
 25     MemoryCache memoryCache=new MemoryCache();
 26     FileCache fileCache;
 27     private Map<ImageView, String> imageViews=Collections.synchronizedMap(new WeakHashMap<ImageView, String>());
 28     ExecutorService executorService; 
 29     
 30     public ImageLoader(Context context){
 31         fileCache=new FileCache(context);
 32         executorService=Executors.newFixedThreadPool(5);
 33     }
 34     
 35     final int stub_id=R.drawable.stub;
 36     public void DisplayImage(String url, ImageView imageView)
 37     {
 38         imageViews.put(imageView, url);
 39         Bitmap bitmap=memoryCache.get(url);
 40         if(bitmap!=null)
 41             imageView.setImageBitmap(bitmap);
 42         else
 43         {
 44             queuePhoto(url, imageView);
 45             imageView.setImageResource(stub_id);
 46         }
 47     }
 48         
 49     private void queuePhoto(String url, ImageView imageView)
 50     {
 51         PhotoToLoad p=new PhotoToLoad(url, imageView);
 52         executorService.submit(new PhotosLoader(p));
 53     }
 54     
 55     private Bitmap getBitmap(String url) 
 56     {
 57         File f=fileCache.getFile(url);
 58         
 59         //from SD cache
 60         Bitmap b = decodeFile(f);
 61         if(b!=null)
 62             return b;
 63         
 64         //from web
 65         try {
 66             Bitmap bitmap=null;
 67             URL imageUrl = new URL(url);
 68             HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
 69             conn.setConnectTimeout(30000);
 70             conn.setReadTimeout(30000);
 71             conn.setInstanceFollowRedirects(true);
 72             InputStream is=conn.getInputStream();
 73             OutputStream os = new FileOutputStream(f);
 74             Utils.CopyStream(is, os);
 75             os.close();
 76             bitmap = decodeFile(f);
 77             return bitmap;
 78         } catch (Exception ex){
 79            ex.printStackTrace();
 80            return null;
 81         }
 82     }
 83 
 84     //decodes image and scales it to reduce memory consumption
 85     private Bitmap decodeFile(File f){
 86         try {
 87             //decode image size
 88             BitmapFactory.Options o = new BitmapFactory.Options();
 89             o.inJustDecodeBounds = true;
 90             BitmapFactory.decodeStream(new FileInputStream(f),null,o);
 91             
 92             //Find the correct scale value. It should be the power of 2.
 93             final int REQUIRED_SIZE=70;
 94             int width_tmp=o.outWidth, height_tmp=o.outHeight;
 95             int scale=1;
 96             while(true){
 97                 if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
 98                     break;
 99                 width_tmp/=2;
100                 height_tmp/=2;
101                 scale*=2;
102             }
103             
104             //decode with inSampleSize
105             BitmapFactory.Options o2 = new BitmapFactory.Options();
106             o2.inSampleSize=scale;
107             return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
108         } catch (FileNotFoundException e) {}
109         return null;
110     }
111     
112     //Task for the queue
113     private class PhotoToLoad
114     {
115         public String url;
116         public ImageView imageView;
117         public PhotoToLoad(String u, ImageView i){
118             url=u; 
119             imageView=i;
120         }
121     }
122     
123     class PhotosLoader implements Runnable {
124         PhotoToLoad photoToLoad;
125         PhotosLoader(PhotoToLoad photoToLoad){
126             this.photoToLoad=photoToLoad;
127         }
128         
129         @Override
130         public void run() {
131             if(imageViewReused(photoToLoad))
132                 return;
133             Bitmap bmp=getBitmap(photoToLoad.url);
134             memoryCache.put(photoToLoad.url, bmp);
135             if(imageViewReused(photoToLoad))
136                 return;
137             BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad);
138             Activity a=(Activity)photoToLoad.imageView.getContext();
139             a.runOnUiThread(bd);
140         }
141     }
142     
143     boolean imageViewReused(PhotoToLoad photoToLoad){
144         String tag=imageViews.get(photoToLoad.imageView);
145         if(tag==null || !tag.equals(photoToLoad.url))
146             return true;
147         return false;
148     }
149     
150     //Used to display bitmap in the UI thread
151     class BitmapDisplayer implements Runnable
152     {
153         Bitmap bitmap;
154         PhotoToLoad photoToLoad;
155         public BitmapDisplayer(Bitmap b, PhotoToLoad p){bitmap=b;photoToLoad=p;}
156         public void run()
157         {
158             if(imageViewReused(photoToLoad))
159                 return;
160             if(bitmap!=null)
161                 photoToLoad.imageView.setImageBitmap(bitmap);
162             else
163                 photoToLoad.imageView.setImageResource(stub_id);
164         }
165     }
166 
167     public void clearCache() {
168         memoryCache.clear();
169         fileCache.clear();
170     }
171 
172 }

 

  1 package com.fedorvlasov.lazylist;

 2 
 3 import android.app.Activity;
 4 import android.content.Context;
 5 import android.view.LayoutInflater;
 6 import android.view.View;
 7 import android.view.ViewGroup;
 8 import android.widget.BaseAdapter;
 9 import android.widget.ImageView;
10 import android.widget.TextView;
11 
12 public class LazyAdapter extends BaseAdapter {
13     
14     private Activity activity;
15     private String[] data;
16     private static LayoutInflater inflater=null;
17     public ImageLoader imageLoader; 
18     
19     public LazyAdapter(Activity a, String[] d) {
20         activity = a;
21         data=d;
22         inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
23         imageLoader=new ImageLoader(activity);
24     }
25 
26     public int getCount() {
27         return data.length;
28     }
29 
30     public Object getItem(int position) {
31         return position;
32     }
33 
34     public long getItemId(int position) {
35         return position;
36     }
37     
38     public View getView(int position, View convertView, ViewGroup parent) {
39         View vi=convertView;
40         if(convertView==null)
41             vi = inflater.inflate(R.layout.item, null);
42 
43         TextView text=(TextView)vi.findViewById(R.id.text);;
44         ImageView image=(ImageView)vi.findViewById(R.id.image);
45         text.setText("item "+position);
46         imageLoader.DisplayImage(data[position], image);
47         return vi;
48     }
49 }

 

  1 package com.fedorvlasov.lazylist;

 2 
 3 import java.io.InputStream;
 4 import java.io.OutputStream;
 5 
 6 public class Utils {
 7     public static void CopyStream(InputStream is, OutputStream os)
 8     {
 9         final int buffer_size=1024;
10         try
11         {
12             byte[] bytes=new byte[buffer_size];
13             for(;;)
14             {
15               int count=is.read(bytes, 0, buffer_size);
16               if(count==-1)
17                   break;
18               os.write(bytes, 0, count);
19             }
20         }
21         catch(Exception ex){}
22     }
23 }

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2012-04-18 15:46  誑逩の蝸犇  阅读(2575)  评论(0编辑  收藏  举报