解决ListView滑动时卡的问题,实现异步加载图片解决 .

ListView是最为常见的空间之一,现在的应用的呈现形式大多数都需要用到ListView来呈现,以列表的方式最直观最便于操作。

那么在使用的过程中大家一定使用adapter适配器来匹配这个ListView,问题就来了,如果直接使用sampleAdapter的话,会出现诸多的问题,诸如滚动的时候很卡,特别是每一行都有头像啊什么的,再加上数据量一大,兼职就卡的不行,那么先来说说解决卡的问题的简单的实现方法吧。

首先需要自己来写一个myAdapter继承与BaseAdapter。

然后最关键的是在getView方法中做到以下几点判断convertView是否为空,这样可以避免每次滚动都去新建,可以节约大量资源,同时对于图片采用开启线程以异步加载的方式来加载它,又可以节约一部分资源,同时,将加载下来的图片缓存到本地,当下一次的时候首先读取本地图片,第一可以节约流量,其次速度非常快(不过服务器图片更新了这个要想好解决方案,不然你本地的图片不会被替换掉)。最后就是在滚动时间的时候让异步加载暂停,等手放开的时候再加载,这样可以保证滚动的超级流畅,不过同时会出现滚动比较大的时候图片都还是空的没有加载的现象,反正自己斟酌优劣吧,代码都有哈!接下来上代码了

首先是主activity

  1. package com.challen;  
  2.   
  3. import java.util.Vector;  
  4.   
  5. import cindy.android.test.synclistview.R;  
  6. import android.app.Activity;  
  7. import android.content.Context;  
  8. import android.graphics.drawable.Drawable;  
  9. import android.os.Bundle;  
  10. import android.os.Handler;  
  11. import android.os.Message;  
  12. import android.view.LayoutInflater;  
  13. import android.view.View;  
  14. import android.view.ViewGroup;  
  15. import android.widget.AbsListView;  
  16. import android.widget.AdapterView;  
  17. import android.widget.BaseAdapter;  
  18. import android.widget.ImageView;  
  19. import android.widget.ListView;  
  20. import android.widget.TextView;  
  21.   
  22. public class TestListViewActivity extends Activity implements  
  23.         AdapterView.OnItemClickListener {  
  24.   
  25.     ListView viewBookList;  
  26.     BookItemAdapter adapter;  
  27.   
  28.     @Override  
  29.     protected void onCreate(Bundle savedInstanceState) {  
  30.         // TODO Auto-generated method stub   
  31.         super.onCreate(savedInstanceState);  
  32.         setContentView(R.layout.main);  
  33.         viewBookList = (ListView) findViewById(R.id.viewBookList);  
  34.   
  35.         adapter = new BookItemAdapter(this, viewBookList);  
  36.   
  37.         viewBookList.setAdapter(adapter);  
  38.         viewBookList.setOnItemClickListener(this);  
  39.         reload();  
  40.     }  
  41.   
  42.     private void reload() {  
  43.         adapter.clean();  
  44.         // loadStateView.startLoad();   
  45.         new Thread(new Runnable() {  
  46.             @Override  
  47.             public void run() {  
  48.                 try {  
  49.                     Thread.sleep(2 * 1000);  
  50.                 } catch (InterruptedException e) {  
  51.                     // TODO Auto-generated catch block   
  52.                     e.printStackTrace();  
  53.                 }  
  54.                 loadDate();  
  55.                 sendMessage(REFRESH_LIST);  
  56.             }  
  57.         }).start();  
  58.     }  
  59.   
  60.     public void loadDate() {  
  61.         for (int i = 0; i < 100; i++) {  
  62.             adapter.addBook("我是challen的测试异步加" + i, "1",  
  63.                     "http://ww1.sinaimg.cn/thumbnail/80ab1ad3gw1dx8tfjvbgdj.jpg");  
  64.   
  65.             adapter.addBook("小美" + i, "2",  
  66.                     "http://ww2.sinaimg.cn/thumbnail/7f9fd9a9jw1dtyrqrh4mjj.jpg");  
  67.   
  68.             adapter.addBook("金总" + i, "3",  
  69.                     "http://ww3.sinaimg.cn/thumbnail/9d57e8e4jw1dx6topumz5j.jpg");  
  70.   
  71.             adapter.addBook("创意铺子" + i, "4",  
  72.                     "http://www.pfwx.com/files/article/image/3/3237/3237s.jpg");  
  73.   
  74.             adapter.addBook("人名日报" + i, "5",  
  75.                     "http://ww2.sinaimg.cn/thumbnail/9263d293jw1dx8snx58s7j.jpg");  
  76.   
  77.             adapter.addBook("名字是乱明的" + i, "6",  
  78.                     "http://tp1.sinaimg.cn/1660452532/50/5646449168/0");  
  79.             adapter.addBook("帅哥即将出现" + i, "7",  
  80.                     "http://p1.qhimg.com/t01a869bb64c7f3d8c6.png");  
  81.             adapter.addBook("注意了哦" + i, "8",  
  82.                     "http://www.baidu.com/img/baidu_jgylogo3.gif");  
  83.             adapter.addBook("来拉" + i, "9",  
  84.                     "http://tp4.sinaimg.cn/2190322767/50/5605436918/1");  
  85.             adapter.addBook("这个就是我啦" + i, "10",  
  86.                     "http://avatar.csdn.net/E/7/2/3_jkingcl.jpg");  
  87.   
  88.         }  
  89.     }  
  90.   
  91.     private static final int REFRESH_LIST = 0x10001;  
  92.     public static final int SHOW_STR_TOAST = 0;  
  93.     public static final int SHOW_RES_TOAST = 1;  
  94.   
  95.     private Handler pichandler = new Handler() {  
  96.         @Override  
  97.         public void handleMessage(Message msg) {  
  98.             if (!Thread.currentThread().isInterrupted()) {  
  99.                 handleOtherMessage(msg.what);  
  100.             }  
  101.         }  
  102.     };  
  103.   
  104.     public void sendMessage(int flag) {  
  105.         pichandler.sendEmptyMessage(flag);  
  106.     }  
  107.   
  108.     protected void handleOtherMessage(int flag) {  
  109.         switch (flag) {  
  110.         case REFRESH_LIST:  
  111.             adapter.notifyDataSetChanged();  
  112.         default:  
  113.             break;  
  114.         }  
  115.     }  
  116.   
  117.     @Override  
  118.     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {  
  119.         // TODO Auto-generated method stub   
  120.   
  121.     }  
  122.   
  123.     public class BookItemAdapter extends BaseAdapter {  
  124.   
  125.         public class BookModel {  
  126.             public String book_id;  
  127.             public String out_book_url;  
  128.             public String author;  
  129.             public String book_state_s;  
  130.             public String leading_role;  
  131.             public String update_time;  
  132.             public String book_name;  
  133.             public String out_book_pic;  
  134.             public String sort_id;  
  135.             public String last_update_section_title;  
  136.             public String last_update_section_url;  
  137.             public String introduction;  
  138.         }  
  139.   
  140.         private LayoutInflater mInflater;  
  141.         private Vector<BookModel> mModels = new Vector<BookModel>();  
  142.         private ListView mListView;  
  143.         SyncImageLoader syncImageLoader;  
  144.   
  145.         public BookItemAdapter(Context context, ListView listView) {  
  146.             mInflater = LayoutInflater.from(context);  
  147.             syncImageLoader = new SyncImageLoader();  
  148.             mListView = listView;  
  149.               
  150.             /* 
  151.              * 
  152.              * 这一句话取消掉注释的话,那么能更加的节省资源,不过体验稍微有点, 
  153.              * 你滑动的时候不会读取图片,当手放开后才开始度图片速度更快,你们可以试一试 
  154.              * */  
  155.               
  156.             // mListView.setOnScrollListener(onScrollListener);   
  157.         }  
  158.   
  159.         public void addBook(String book_name, String author, String out_book_pic) {  
  160.             BookModel model = new BookModel();  
  161.             model.book_name = book_name;  
  162.             model.author = author;  
  163.             model.out_book_pic = out_book_pic;  
  164.             mModels.add(model);  
  165.         }  
  166.   
  167.         public void clean() {  
  168.             mModels.clear();  
  169.         }  
  170.   
  171.         @Override  
  172.         public int getCount() {  
  173.             // TODO Auto-generated method stub   
  174.             return mModels.size();  
  175.         }  
  176.   
  177.         @Override  
  178.         public Object getItem(int position) {  
  179.             if (position >= getCount()) {  
  180.                 return null;  
  181.             }  
  182.             return mModels.get(position);  
  183.         }  
  184.   
  185.         @Override  
  186.         public long getItemId(int position) {  
  187.             // TODO Auto-generated method stub   
  188.             return position;  
  189.         }  
  190.   
  191.         @Override  
  192.         public View getView(int position, View convertView, ViewGroup parent) {  
  193.             if (convertView == null) {  
  194.                 convertView = mInflater.inflate(R.layout.item_adapter,  
  195.                         null);  
  196.             }  
  197.             BookModel model = mModels.get(position);  
  198.             convertView.setTag(position);  
  199.             ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);  
  200.             TextView sItemTitle = (TextView) convertView  
  201.                     .findViewById(R.id.sItemTitle);  
  202.             TextView sItemInfo = (TextView) convertView  
  203.                     .findViewById(R.id.sItemInfo);  
  204.             sItemTitle.setText(model.book_name);  
  205.             sItemInfo.setText(model.out_book_url);  
  206.             // 添加�?��背景在滑动的时�?就会显示背景而不是其他的缓存的照片,用户体验更好   
  207.             iv.setBackgroundResource(R.drawable.rc_item_bg);  
  208.             syncImageLoader.loadImage(position, model.out_book_pic,  
  209.                     imageLoadListener, model.author);  
  210.             return convertView;  
  211.         }  
  212.   
  213.         SyncImageLoader.OnImageLoadListener imageLoadListener = new SyncImageLoader.OnImageLoadListener() {  
  214.   
  215.             @Override  
  216.             public void onImageLoad(Integer t, Drawable drawable) {  
  217.                 // BookModel model = (BookModel) getItem(t);   
  218.                 View view = mListView.findViewWithTag(t);  
  219.                 if (view != null) {  
  220.                     ImageView iv = (ImageView) view  
  221.                             .findViewById(R.id.sItemIcon);  
  222.                     iv.setBackgroundDrawable(drawable);  
  223.                 }  
  224.             }  
  225.   
  226.             @Override  
  227.             public void onError(Integer t) {  
  228.                 BookModel model = (BookModel) getItem(t);  
  229.                 View view = mListView.findViewWithTag(model);  
  230.                 if (view != null) {  
  231.                     ImageView iv = (ImageView) view  
  232.                             .findViewById(R.id.sItemIcon);  
  233.                     iv.setBackgroundResource(R.drawable.rc_item_bg);  
  234.                 }  
  235.             }  
  236.   
  237.         };  
  238.   
  239.         public void loadImage() {  
  240.             int start = mListView.getFirstVisiblePosition();  
  241.             int end = mListView.getLastVisiblePosition();  
  242.             if (end >= getCount()) {  
  243.                 end = getCount() - 1;  
  244.             }  
  245.             syncImageLoader.setLoadLimit(start, end);  
  246.             syncImageLoader.unlock();  
  247.         }  
  248.   
  249.         AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {  
  250.   
  251.             @Override  
  252.             public void onScrollStateChanged(AbsListView view, int scrollState) {  
  253.                 switch (scrollState) {  
  254.                 case AbsListView.OnScrollListener.SCROLL_STATE_FLING:  
  255.                     syncImageLoader.lock();  
  256.                     break;  
  257.                 case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:  
  258.                     loadImage();  
  259.                     break;  
  260.                 case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:  
  261.                     syncImageLoader.lock();  
  262.                     break;  
  263.   
  264.                 default:  
  265.                     break;  
  266.                 }  
  267.   
  268.             }  
  269.   
  270.             @Override  
  271.             public void onScroll(AbsListView view, int firstVisibleItem,  
  272.                     int visibleItemCount, int totalItemCount) {  
  273.                 // TODO Auto-generated method stub   
  274.   
  275.             }  
  276.         };  
  277.     }  
  278.   
  279. }  
package com.challen;

import java.util.Vector;

import cindy.android.test.synclistview.R;
import android.app.Activity;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class TestListViewActivity extends Activity implements
		AdapterView.OnItemClickListener {

	ListView viewBookList;
	BookItemAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		viewBookList = (ListView) findViewById(R.id.viewBookList);

		adapter = new BookItemAdapter(this, viewBookList);

		viewBookList.setAdapter(adapter);
		viewBookList.setOnItemClickListener(this);
		reload();
	}

	private void reload() {
		adapter.clean();
		// loadStateView.startLoad();
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					Thread.sleep(2 * 1000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				loadDate();
				sendMessage(REFRESH_LIST);
			}
		}).start();
	}

	public void loadDate() {
		for (int i = 0; i < 100; i++) {
			adapter.addBook("我是challen的测试异步加" + i, "1",
					"http://ww1.sinaimg.cn/thumbnail/80ab1ad3gw1dx8tfjvbgdj.jpg");

			adapter.addBook("小美" + i, "2",
					"http://ww2.sinaimg.cn/thumbnail/7f9fd9a9jw1dtyrqrh4mjj.jpg");

			adapter.addBook("金总" + i, "3",
					"http://ww3.sinaimg.cn/thumbnail/9d57e8e4jw1dx6topumz5j.jpg");

			adapter.addBook("创意铺子" + i, "4",
					"http://www.pfwx.com/files/article/image/3/3237/3237s.jpg");

			adapter.addBook("人名日报" + i, "5",
					"http://ww2.sinaimg.cn/thumbnail/9263d293jw1dx8snx58s7j.jpg");

			adapter.addBook("名字是乱明的" + i, "6",
					"http://tp1.sinaimg.cn/1660452532/50/5646449168/0");
			adapter.addBook("帅哥即将出现" + i, "7",
					"http://p1.qhimg.com/t01a869bb64c7f3d8c6.png");
			adapter.addBook("注意了哦" + i, "8",
					"http://www.baidu.com/img/baidu_jgylogo3.gif");
			adapter.addBook("来拉" + i, "9",
					"http://tp4.sinaimg.cn/2190322767/50/5605436918/1");
			adapter.addBook("这个就是我啦" + i, "10",
					"http://avatar.csdn.net/E/7/2/3_jkingcl.jpg");

		}
	}

	private static final int REFRESH_LIST = 0x10001;
	public static final int SHOW_STR_TOAST = 0;
	public static final int SHOW_RES_TOAST = 1;

	private Handler pichandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			if (!Thread.currentThread().isInterrupted()) {
				handleOtherMessage(msg.what);
			}
		}
	};

	public void sendMessage(int flag) {
		pichandler.sendEmptyMessage(flag);
	}

	protected void handleOtherMessage(int flag) {
		switch (flag) {
		case REFRESH_LIST:
			adapter.notifyDataSetChanged();
		default:
			break;
		}
	}

	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
		// TODO Auto-generated method stub

	}

	public class BookItemAdapter extends BaseAdapter {

		public class BookModel {
			public String book_id;
			public String out_book_url;
			public String author;
			public String book_state_s;
			public String leading_role;
			public String update_time;
			public String book_name;
			public String out_book_pic;
			public String sort_id;
			public String last_update_section_title;
			public String last_update_section_url;
			public String introduction;
		}

		private LayoutInflater mInflater;
		private Vector<BookModel> mModels = new Vector<BookModel>();
		private ListView mListView;
		SyncImageLoader syncImageLoader;

		public BookItemAdapter(Context context, ListView listView) {
			mInflater = LayoutInflater.from(context);
			syncImageLoader = new SyncImageLoader();
			mListView = listView;
			
			/*
			 *
			 * 这一句话取消掉注释的话,那么能更加的节省资源,不过体验稍微有点,
			 * 你滑动的时候不会读取图片,当手放开后才开始度图片速度更快,你们可以试一试
			 * */
			
			// mListView.setOnScrollListener(onScrollListener);
		}

		public void addBook(String book_name, String author, String out_book_pic) {
			BookModel model = new BookModel();
			model.book_name = book_name;
			model.author = author;
			model.out_book_pic = out_book_pic;
			mModels.add(model);
		}

		public void clean() {
			mModels.clear();
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return mModels.size();
		}

		@Override
		public Object getItem(int position) {
			if (position >= getCount()) {
				return null;
			}
			return mModels.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.item_adapter,
						null);
			}
			BookModel model = mModels.get(position);
			convertView.setTag(position);
			ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
			TextView sItemTitle = (TextView) convertView
					.findViewById(R.id.sItemTitle);
			TextView sItemInfo = (TextView) convertView
					.findViewById(R.id.sItemInfo);
			sItemTitle.setText(model.book_name);
			sItemInfo.setText(model.out_book_url);
			// 添加�?��背景在滑动的时�?就会显示背景而不是其他的缓存的照片,用户体验更好
			iv.setBackgroundResource(R.drawable.rc_item_bg);
			syncImageLoader.loadImage(position, model.out_book_pic,
					imageLoadListener, model.author);
			return convertView;
		}

		SyncImageLoader.OnImageLoadListener imageLoadListener = new SyncImageLoader.OnImageLoadListener() {

			@Override
			public void onImageLoad(Integer t, Drawable drawable) {
				// BookModel model = (BookModel) getItem(t);
				View view = mListView.findViewWithTag(t);
				if (view != null) {
					ImageView iv = (ImageView) view
							.findViewById(R.id.sItemIcon);
					iv.setBackgroundDrawable(drawable);
				}
			}

			@Override
			public void onError(Integer t) {
				BookModel model = (BookModel) getItem(t);
				View view = mListView.findViewWithTag(model);
				if (view != null) {
					ImageView iv = (ImageView) view
							.findViewById(R.id.sItemIcon);
					iv.setBackgroundResource(R.drawable.rc_item_bg);
				}
			}

		};

		public void loadImage() {
			int start = mListView.getFirstVisiblePosition();
			int end = mListView.getLastVisiblePosition();
			if (end >= getCount()) {
				end = getCount() - 1;
			}
			syncImageLoader.setLoadLimit(start, end);
			syncImageLoader.unlock();
		}

		AbsListView.OnScrollListener onScrollListener = new AbsListView.OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				switch (scrollState) {
				case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
					syncImageLoader.lock();
					break;
				case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
					loadImage();
					break;
				case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
					syncImageLoader.lock();
					break;

				default:
					break;
				}

			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem,
					int visibleItemCount, int totalItemCount) {
				// TODO Auto-generated method stub

			}
		};
	}

}


其次是实现异步加载和缓存图片的功能代码loader.java

  1. package com.challen;  
  2.   
  3. import java.io.DataInputStream;  
  4. import java.io.File;  
  5. import java.io.FileInputStream;  
  6. import java.io.FileOutputStream;  
  7. import java.io.IOException;  
  8. import java.io.InputStream;  
  9. import java.lang.ref.SoftReference;  
  10. import java.net.URL;  
  11. import java.util.HashMap;  
  12.   
  13. import android.graphics.drawable.Drawable;  
  14. import android.os.Environment;  
  15. import android.os.Handler;  
  16.   
  17. public class SyncImageLoader {  
  18.   
  19.     private Object lock = new Object();  
  20.       
  21.     private boolean mAllowLoad = true;  
  22.       
  23.     private boolean firstLoad = true;  
  24.       
  25.     private int mStartLoadLimit = 0;  
  26.       
  27.     private int mStopLoadLimit = 0;  
  28.       
  29.     final Handler handler = new Handler();  
  30.       
  31.     private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();     
  32.       
  33.     public interface OnImageLoadListener {  
  34.         public void onImageLoad(Integer t, Drawable drawable);  
  35.         public void onError(Integer t);  
  36.     }  
  37.       
  38.     public void setLoadLimit(int startLoadLimit,int stopLoadLimit){  
  39.         if(startLoadLimit > stopLoadLimit){  
  40.             return;  
  41.         }  
  42.         mStartLoadLimit = startLoadLimit;  
  43.         mStopLoadLimit = stopLoadLimit;  
  44.     }  
  45.       
  46.     public void restore(){  
  47.         mAllowLoad = true;  
  48.         firstLoad = true;  
  49.     }  
  50.           
  51.     public void lock(){  
  52.         mAllowLoad = false;  
  53.         firstLoad = false;  
  54.     }  
  55.       
  56.     public void unlock(){  
  57.         mAllowLoad = true;  
  58.         synchronized (lock) {  
  59.             lock.notifyAll();  
  60.         }  
  61.     }  
  62.   
  63.     public void loadImage(Integer t, String imageUrl,  
  64.             OnImageLoadListener listener,String author1) {  
  65.         final OnImageLoadListener mListener = listener;  
  66.         final String mImageUrl = imageUrl;  
  67.         final Integer mt = t;  
  68.         final String author = author1;  
  69.           
  70.         new Thread(new Runnable() {  
  71.   
  72.             @Override  
  73.             public void run() {  
  74.                 if(!mAllowLoad){  
  75.                     synchronized (lock) {  
  76.                         try {  
  77.                             lock.wait();  
  78.                         } catch (InterruptedException e) {  
  79.                             // TODO Auto-generated catch block   
  80.                             e.printStackTrace();  
  81.                         }  
  82.                     }  
  83.                 }  
  84.                   
  85.                 if(mAllowLoad && firstLoad){  
  86.                     loadImage(mImageUrl, mt, mListener,author);  
  87.                 }  
  88.                   
  89.                 if(mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit){  
  90.                     loadImage(mImageUrl, mt, mListener,author);  
  91.                 }  
  92.             }  
  93.   
  94.         }).start();  
  95.     }  
  96.       
  97.     private void loadImage(final String mImageUrl,final Integer mt,final OnImageLoadListener mListener,final String author){  
  98.           
  99.         if (imageCache.containsKey(mImageUrl)) {    
  100.             System.out.println("drawable");  
  101.             SoftReference<Drawable> softReference = imageCache.get(mImageUrl);    
  102.             final Drawable d = softReference.get();    
  103.             if (d != null) {    
  104.                 handler.post(new Runnable() {  
  105.                     @Override  
  106.                     public void run() {  
  107.                         if(mAllowLoad){  
  108.                             mListener.onImageLoad(mt, d);  
  109.                         }  
  110.                     }  
  111.                 });  
  112.                 return;    
  113.             }    
  114.         }    
  115.         try {  
  116.             final Drawable d = loadImageFromUrl(mImageUrl,author);  
  117.             if(d != null){  
  118.                 imageCache.put(mImageUrl, new SoftReference<Drawable>(d));  
  119.             }  
  120.             handler.post(new Runnable() {  
  121.                 @Override  
  122.                 public void run() {  
  123.                     if(mAllowLoad){  
  124.                         mListener.onImageLoad(mt, d);  
  125.                     }  
  126.                 }  
  127.             });  
  128.         } catch (IOException e) {  
  129.             handler.post(new Runnable() {  
  130.                 @Override  
  131.                 public void run() {  
  132.                     mListener.onError(mt);  
  133.                 }  
  134.             });  
  135.             e.printStackTrace();  
  136.         }  
  137.     }  
  138.   
  139.     public static Drawable loadImageFromUrl(String url,String author) throws IOException {  
  140.         //是否SD卡可用   
  141.         if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){  
  142.             //检查是或有保存图片的文件夹,没有就穿件一个   
  143.             String FileUrl = Environment.getExternalStorageDirectory()+"/TestSyncListView/";  
  144.             File folder = new File(FileUrl);  
  145.             if(!folder.exists()){  
  146.                 folder.mkdir();  
  147.             }  
  148.             File f = new File(FileUrl+author+".jpg");  
  149.             //SD卡中是否有该文件,有则直接读取返回   
  150.             if(f.exists()){  
  151.                 FileInputStream fis = new FileInputStream(f);  
  152.                 Drawable d = Drawable.createFromStream(fis, "src");  
  153.                 return d;  
  154.             }  
  155.             //没有的话则去连接下载,并写入到SD卡中   
  156.             URL m = new URL(url);  
  157.             InputStream i = (InputStream) m.getContent();  
  158.             DataInputStream in = new DataInputStream(i);  
  159.             FileOutputStream out = new FileOutputStream(f);  
  160.             byte[] buffer = new byte[1024];  
  161.             int   byteread=0;  
  162.             while ((byteread = in.read(buffer)) != -1) {  
  163.                 out.write(buffer, 0, byteread);  
  164.             }  
  165.             in.close();  
  166.             out.close();  
  167.             Drawable d = Drawable.createFromStream(i, "src");  
  168.             return loadImageFromUrl(url,author);  
  169.         }  
  170.         //SD卡不可用则直接加载使用   
  171.         else{  
  172.             URL m = new URL(url);  
  173.             InputStream i = (InputStream) m.getContent();  
  174.             Drawable d = Drawable.createFromStream(i, "src");  
  175.             return d;  
  176.         }  
  177.           
  178.     }  
  179. }  
package com.challen;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.util.HashMap;

import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;

public class SyncImageLoader {

	private Object lock = new Object();
	
	private boolean mAllowLoad = true;
	
	private boolean firstLoad = true;
	
	private int mStartLoadLimit = 0;
	
	private int mStopLoadLimit = 0;
	
	final Handler handler = new Handler();
	
	private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();   
	
	public interface OnImageLoadListener {
		public void onImageLoad(Integer t, Drawable drawable);
		public void onError(Integer t);
	}
	
	public void setLoadLimit(int startLoadLimit,int stopLoadLimit){
		if(startLoadLimit > stopLoadLimit){
			return;
		}
		mStartLoadLimit = startLoadLimit;
		mStopLoadLimit = stopLoadLimit;
	}
	
	public void restore(){
		mAllowLoad = true;
		firstLoad = true;
	}
		
	public void lock(){
		mAllowLoad = false;
		firstLoad = false;
	}
	
	public void unlock(){
		mAllowLoad = true;
		synchronized (lock) {
			lock.notifyAll();
		}
	}

	public void loadImage(Integer t, String imageUrl,
			OnImageLoadListener listener,String author1) {
		final OnImageLoadListener mListener = listener;
		final String mImageUrl = imageUrl;
		final Integer mt = t;
		final String author = author1;
		
		new Thread(new Runnable() {

			@Override
			public void run() {
				if(!mAllowLoad){
					synchronized (lock) {
						try {
							lock.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				
				if(mAllowLoad && firstLoad){
					loadImage(mImageUrl, mt, mListener,author);
				}
				
				if(mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit){
					loadImage(mImageUrl, mt, mListener,author);
				}
			}

		}).start();
	}
	
	private void loadImage(final String mImageUrl,final Integer mt,final OnImageLoadListener mListener,final String author){
		
		if (imageCache.containsKey(mImageUrl)) {  
			System.out.println("drawable");
            SoftReference<Drawable> softReference = imageCache.get(mImageUrl);  
            final Drawable d = softReference.get();  
            if (d != null) {  
            	handler.post(new Runnable() {
    				@Override
    				public void run() {
    					if(mAllowLoad){
    						mListener.onImageLoad(mt, d);
    					}
    				}
    			});
                return;  
            }  
        }  
		try {
			final Drawable d = loadImageFromUrl(mImageUrl,author);
			if(d != null){
                imageCache.put(mImageUrl, new SoftReference<Drawable>(d));
			}
			handler.post(new Runnable() {
				@Override
				public void run() {
					if(mAllowLoad){
						mListener.onImageLoad(mt, d);
					}
				}
			});
		} catch (IOException e) {
			handler.post(new Runnable() {
				@Override
				public void run() {
					mListener.onError(mt);
				}
			});
			e.printStackTrace();
		}
	}

	public static Drawable loadImageFromUrl(String url,String author) throws IOException {
		//是否SD卡可用
		if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
			//检查是或有保存图片的文件夹,没有就穿件一个
			String FileUrl = Environment.getExternalStorageDirectory()+"/TestSyncListView/";
			File folder = new File(FileUrl);
			if(!folder.exists()){
				folder.mkdir();
			}
			File f = new File(FileUrl+author+".jpg");
			//SD卡中是否有该文件,有则直接读取返回
			if(f.exists()){
				FileInputStream fis = new FileInputStream(f);
				Drawable d = Drawable.createFromStream(fis, "src");
				return d;
			}
			//没有的话则去连接下载,并写入到SD卡中
			URL m = new URL(url);
			InputStream i = (InputStream) m.getContent();
			DataInputStream in = new DataInputStream(i);
			FileOutputStream out = new FileOutputStream(f);
			byte[] buffer = new byte[1024];
			int   byteread=0;
			while ((byteread = in.read(buffer)) != -1) {
				out.write(buffer, 0, byteread);
			}
			in.close();
			out.close();
			Drawable d = Drawable.createFromStream(i, "src");
			return loadImageFromUrl(url,author);
		}
		//SD卡不可用则直接加载使用
		else{
			URL m = new URL(url);
			InputStream i = (InputStream) m.getContent();
			Drawable d = Drawable.createFromStream(i, "src");
			return d;
		}
		
	}
}


 

 

最后附上整个测试demo的下载地址,各位可以去下载,然后根据自己的需求加入到自己的项目中,希望可以帮助到大家,大家多多交流哦!

http://download.csdn.net/detail/jkingcl/4726519

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值