我们今天在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;
}