首页 > 代码库 > android 队列模仿listview同步加载图片

android 队列模仿listview同步加载图片

我们今天在listview加载图片都是异步的,如果有个需求要求listview同步加载图片,同步加载图片是什么意思呢?就是第一张图片下载好了,然后接着第二张图片下载,依次类推,今天就简单的模仿写个简单的,而且下载的图片还要缓存到SD卡中

思路:

队列是用LinkedList集合模拟,

缓存:当图片下载成功了把当前图片对应的url经过md5加密存到sd卡中的某个子文件夹下,当用户再次进来的时候,可以adapter中判断这个url是否存在,如果存在就加载这个url对应的图片,就达到了缓存的目的

代码如下:

public class MainActivity extends Activity implements OnItemClickListener,DownLoadSuccess{
	private ListView lv;
	private List<String> pics = new ArrayList<String>();
	
	private FrameAdapter adapter;
	private DownLoadUtil downLoadUtil;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		lv = (ListView) findViewById(R.id.lv);
		
		pics.add("http://img3.douban.com/view/photo/albumcover/public/p2214024212.jpg");
		pics.add("http://img3.douban.com/view/photo/albumcover/public/p2204417742.jpg");
		pics.add("http://img5.douban.com/view/photo/albumcover/public/p2214440886.jpg");
		pics.add("http://img3.douban.com/view/photo/albumcover/public/p2200048400.jpg");
		pics.add("http://img3.douban.com/view/commodity_story/medium/public/p11589841.jpg");
		pics.add("http://img5.douban.com/view/commodity_story/small/public/p8220077.jpg");
		pics.add("http://img5.douban.com/view/commodity_story/small/public/p9683297.jpg");
		pics.add("http://img3.douban.com/view/commodity_story/small/public/p9581674.jpg");
		pics.add("http://img5.douban.com/view/commodity_story/small/public/p11824477.jpg");
		
		adapter = new FrameAdapter();
		downLoadUtil = new DownLoadUtil(this,adapter);
		lv.setAdapter(adapter);
		
		lv.setOnItemClickListener(this);
	}
	
	public class FrameAdapter extends BaseAdapter {
		private int position =-1;
		

		public void setPosition(int position) {
			this.position = position;
		}

		@Override
		public int getCount() {
			pics.size();
			return (pics==null||pics.isEmpty())?0:pics.size();
		}

		@Override
		public Object getItem(int position) {
			return pics.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View converView, ViewGroup arg2) {
			ViewHolder holder;
			if(converView==null){
				converView = View.inflate(getApplicationContext(), R.layout.item, null);
				holder = new ViewHolder();
				holder.bindView(converView);
				converView.setTag(holder);
			}else{
				holder = (ViewHolder) converView.getTag();
			}
			holder.reset(position);
			return converView;
		}
		
		class ViewHolder{
			ImageView iv_frame;
			private View converView;
			public void bindView(View converView) {
				this.converView = converView;
				iv_frame  = (ImageView) converView.findViewById(R.id.iv_frame);
			}
			public void reset(int position){
				String url = pics.get(position);
				String tempPath = MD5Utils.md5(Utils.replaceUrl(url).trim());//
				final String sdTopPath = String.format("%s%s", CacheFileUtils.getSnapartFramesRootPath(), tempPath);//sd卡路径
				if(CacheFileUtils.isExists(sdTopPath)){
					Bitmap bitmap = BitmapFactory.decodeFile(sdTopPath);
					iv_frame.setImageBitmap(bitmap);
				}else{
					//
					iv_frame.setImageResource(R.drawable.frame_loadingmore);
				}
			}
		}
	}
	@Override
	public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
		String url = pics.get(position);
		if(TextUtils.isEmpty(url)){
			Toast.makeText(this, "文件不能下载,请检查你的网络", 0).show();
			return;
		}
		String tempPath = MD5Utils.md5(Utils.replaceUrl(url).trim());//
		final String sdTopPath = String.format("%s%s", CacheFileUtils.getSnapartFramesRootPath(), tempPath);//sd卡路径
		if(!CacheFileUtils.isExists(sdTopPath)){
			downLoadUtil.execute(pics.get(position));
		}else{
			Toast.makeText(this, "文件已存在", 0).show();
		}
	}
	
	public  Handler handler = new Handler(){
		public void handleMessage(android.os.Message msg) {
			 if(msg.what==1){
				 adapter.notifyDataSetChanged();
			 }
		}
};
	@Override
	public void onSuccess() {
		handler.sendEmptyMessage(1);
	} 
}

下载的类:

DownLoadUtil.java

public class DownLoadUtil {
	private static Context context;
	public static final String TAG = "DownLoadUtil";
	Thread thread;
	private boolean isDownLoadOver = false;
	private int position;
	private static DownLoadUtil instance = null;
	private DownLoadSuccess downLoadSuccess;
	private FrameAdapter adapter;
	private Task task;
	
	private ExecutorService newSingleThreadExecutor;
	private LinkedList<String> ll = new LinkedList<String>();
	private Set<String> strContent = new HashSet<String>();
	private Handler handler = new Handler(){
		   public void handleMessage(android.os.Message msg) {
			     if(msg.what==1){
			    	 adapter.notifyDataSetChanged();
			    	 isDownLoadOver = false;
			    	 checkDownLoad();
			     }
		   }
	};
	public void setDownLoadSuccess(DownLoadSuccess downLoadSuccess) {
		this.downLoadSuccess = downLoadSuccess;
	}

	public  DownLoadUtil(Context context,FrameAdapter adapter) {
		this.context = context;
		this.adapter = adapter;
		newSingleThreadExecutor = Executors.newSingleThreadExecutor();
		task = new Task();
	}
	
	public void execute(String url) {
		if (!ll.contains(url)) {
			ll.addLast(url);
			task.setUrl(url);
			//把task放入
			download();
		}
	}
	private void destoryDownLoadThread() {
		if (null != thread && Thread.State.RUNNABLE == thread.getState()) {
			try {
				Thread.sleep(500);
				thread.interrupt();
			} catch (Exception e) {
				thread = null;
			}
		}
		thread = null;
	}

	public void download() {
		if (!isDownLoadOver) {
			isDownLoadOver = true;
			if(ll.size()>0){
				String downUrl = ll.getFirst();
				if(!TextUtils.isEmpty(downUrl)){
					task.setUrl(downUrl);
					newSingleThreadExecutor.execute(task);
				}
			}
		}
	}
	public void checkDownLoad() {
		ll.removeFirst();
		if(!ll.isEmpty()){
			download();
		}
	}
	
	public interface DownLoadSuccess{
		public void onSuccess();
	}
	
	class Task implements Runnable {
		public String url;
		
		public Task() {
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public Task(String url) {
			this.url = url;
		}

		@Override
		public void run() {
			if (isDownLoadOver) {
				InputStream inputStream = null;
				FileOutputStream fos = null;
				try {
					URL murl = new URL(url);
					HttpURLConnection conn = (HttpURLConnection) murl.openConnection();
					inputStream = conn.getInputStream();
				    String tempPath = MD5Utils.md5(Utils.replaceUrl(url).trim());//
				    final String sdTopPath = String.format("%s%s", CacheFileUtils.getSnapartFramesRootPath(), tempPath);//sd卡路径
					File file = new File(sdTopPath);
					fos = new FileOutputStream(file);
					byte[] buff = new byte[1024];
					int len = 0;
					while ((len = inputStream.read(buff)) != -1) {
						fos.write(buff, 0, len);
					}
				} 
				catch (MalformedURLException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				} finally {
					if (inputStream != null) {
						try {
							inputStream.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
					if (fos != null) {
						try {
							fos.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
					handler.sendEmptyMessage(1);
			}
		}
	  }
	}
}

CacheFileUtils.java 缓存的工具类

public static boolean isExists(String fileName) {
		if (TextUtils.isEmpty(fileName)) {
			return false;
		}
		File file = new File(fileName);
		return file.exists();
	}

/**
	 * 
	 * @return
	 */
	public static String getSnapartFramesRootPath() {
		String sdcardPath = getSDPath();
		StringBuffer fileSB = new StringBuffer();
		fileSB.append(sdcardPath).append(File.separator).append(ConfigManager.APP_FOLDER);
		fileSB.append(File.separator).append(ConfigManager.CACHE_SNAPART_FRAMES).append(File.separator);
		// 文件夹问null时构造
		String rootPath = fileSB.toString();
		File destDir = new File(rootPath);
		if (!destDir.exists() || destDir.getAbsoluteFile() == null) {
			destDir.mkdirs();
		}
		return rootPath;
	}


android 队列模仿listview同步加载图片