前言:本以为异步加载挺简单,因为网上代码多,但真想要做好,还真不那么简单,从看代码到弄懂再到自己写,实在是有太多的东西需要学了,用了两天的时间,终于弄出来了,因为用到回调函数,所以理解起来可能难度有点大,讲起来也不太好讲,我尽力讲的明白些,其实还是要多看代码,自己摸索摸索,动手写写就什么都理解了。这篇我们只讲怎样实现异步加载,对于滑动时停止加载的事下篇再讲。

实现效果:

1、异步加载图片,在加载图片时,先加载一个默认的图片,然后在后台加载图片,加载完成后显示出来;

2、当用户在滑动时,停止加载图片的线程,当停止滑动时,看哪几个ITEM在显示屏内,只加载这几个,其它线程保持阻止;(下篇再讲)

效果图:

刚开始加载时                          向下划动(新划出来的是空白块)           停划,加载完成

   

一、XML

1、main.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <ListView android:id="@+id/list"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent" />
  10. </LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>

2、列表子项XML(book_item_adapter.xml)

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="70.0dip"
  5. android:background="@drawable/item"
  6. android:drawingCacheQuality="high"
  7. android:minHeight="70.0dip"
  8. android:orientation="horizontal" >
  9. <ImageView
  10. android:id="@+id/sItemIcon"
  11. android:layout_width="42.0dip"
  12. android:layout_height="54.0dip"
  13. android:layout_margin="10.0dip"
  14. android:background="@drawable/rc_item_bg"
  15. android:padding="2.0dip"
  16. android:scaleType="fitXY" />
  17. <TextView
  18. android:text="斗破苍穹"
  19. android:id="@+id/sItemTitle"
  20. android:layout_width="fill_parent"
  21. android:layout_height="30.0dip"
  22. android:layout_alignTop="@+id/sItemIcon"
  23. android:layout_toRightOf="@+id/sItemIcon"
  24. android:gravity="center_vertical"
  25. android:singleLine="true"
  26. android:textColor="#ffffff"
  27. android:textSize="18.0sp" />
  28. </RelativeLayout>
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70.0dip"
android:background="@drawable/item"
android:drawingCacheQuality="high"
android:minHeight="70.0dip"
android:orientation="horizontal" > <ImageView
android:id="@+id/sItemIcon"
android:layout_width="42.0dip"
android:layout_height="54.0dip"
android:layout_margin="10.0dip"
android:background="@drawable/rc_item_bg"
android:padding="2.0dip"
android:scaleType="fitXY" /> <TextView
android:text="斗破苍穹"
android:id="@+id/sItemTitle"
android:layout_width="fill_parent"
android:layout_height="30.0dip"
android:layout_alignTop="@+id/sItemIcon"
android:layout_toRightOf="@+id/sItemIcon"
android:gravity="center_vertical"
android:singleLine="true"
android:textColor="#ffffff"
android:textSize="18.0sp" />
</RelativeLayout>

二、JAVA代码

1、主页面代码(AsyncListImage.java)

  1. package cn.wangmeng.test;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import android.app.Activity;
  5. import android.os.Bundle;
  6. import android.widget.ListView;
  7. public class AsyncListImage extends Activity {
  8. private ListView list;
  9. @Override
  10. public void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. setContentView(R.layout.main);
  13. list=(ListView)findViewById(R.id.list);
  14. List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
  15. for (int i = 0; i < 100; i++) {
  16. ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");
  17. ImageAndText test1=new ImageAndText("http://www.pfwx.com/files/article/image/0/54/54s.jpg", "test1");
  18. ImageAndText test2=new ImageAndText("http://www.pfwx.com/files/article/image/0/4/4s.jpg","test2");
  19. ImageAndText test3=new ImageAndText("http://www.pfwx.com/files/article/image/9/9760/9760s.jpg","test3");
  20. ImageAndText test4=new ImageAndText("http://www.pfwx.com/files/article/image/3/3382/3382s.jpg","test4");
  21. ImageAndText test5=new ImageAndText("http://www.pfwx.com/files/article/image/3/3237/3237s.jpg","test5");
  22. dataArray.add(test);
  23. dataArray.add(test1);
  24. dataArray.add(test2);
  25. dataArray.add(test3);
  26. dataArray.add(test4);
  27. dataArray.add(test5);
  28. }
  29. ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);
  30. list.setAdapter(adapter);
  31. }
  32. }
package cn.wangmeng.test;

import java.util.ArrayList;
import java.util.List; import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView; public class AsyncListImage extends Activity {
private ListView list;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list=(ListView)findViewById(R.id.list);
List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
for (int i = 0; i < 100; i++) {
ImageAndText test=new ImageAndText("http://www.wangmeng.cn/images/logo.gif", "test");
ImageAndText test1=new ImageAndText("http://www.pfwx.com/files/article/image/0/54/54s.jpg", "test1");
ImageAndText test2=new ImageAndText("http://www.pfwx.com/files/article/image/0/4/4s.jpg","test2");
ImageAndText test3=new ImageAndText("http://www.pfwx.com/files/article/image/9/9760/9760s.jpg","test3");
ImageAndText test4=new ImageAndText("http://www.pfwx.com/files/article/image/3/3382/3382s.jpg","test4");
ImageAndText test5=new ImageAndText("http://www.pfwx.com/files/article/image/3/3237/3237s.jpg","test5");
dataArray.add(test);
dataArray.add(test1);
dataArray.add(test2);
dataArray.add(test3);
dataArray.add(test4);
dataArray.add(test5); } ImageAndTextListAdapter adapter=new ImageAndTextListAdapter(this, dataArray, list);
list.setAdapter(adapter); }
}

2、ImageAndText.java

  1. package cn.wangmeng.test;
  2. public class ImageAndText {
  3. private String imageUrl;
  4. private String text;
  5. public ImageAndText(String imageUrl, String text) {
  6. this.imageUrl = imageUrl;
  7. this.text = text;
  8. }
  9. public String getImageUrl() {
  10. return imageUrl;
  11. }
  12. public String getText() {
  13. return text;
  14. }
  15. }
package cn.wangmeng.test;

public class ImageAndText {
private String imageUrl;
private String text; public ImageAndText(String imageUrl, String text) {
this.imageUrl = imageUrl;
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public String getText() {
return text;
}
}

上面两个代码一块讲 1、ImageAndText类是用来存储要与XML绑定的图片地址和名字地址的。

2、将所有的地址都放在一个List里面(dataArray),然后将其传入ImageAndTextListAdapter()函数中;可见这个ImageAndTextListAdapter()函数是根据传进去的dataArray生成对应的Adapter的

3、然后将ImageAndTextListAdapter()返回的Adapter与listView绑定

3、ImageAndTextListAdapter.java

这是重写于baseAdapter的类,由于重写于baseAdapter,所以有几个必须重写的函数,getCount()、getItem()、getItemId()、getView(),我们先把总体代码写出来,只讲一个getView()函数,其实函数就不讲了,先着重说下getView()函数在什么时候被系统调用:

getView()函数在什么时候被系统调用:

注意一点是android系统在显示列表时,并不是把所有代表都显示出来,让你随便划,划到哪是哪;而是根据当前的在划到的ITEM,调用当前ITEM的getView()来显示它。

全部代码:

  1. package cn.wangmeng.test;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import cn.wangmeng.test.AsyncImageLoader.ImageCallback;
  5. import android.app.Activity;
  6. import android.graphics.drawable.Drawable;
  7. import android.util.Log;
  8. import android.view.LayoutInflater;
  9. import android.view.View;
  10. import android.view.ViewGroup;
  11. import android.widget.ArrayAdapter;
  12. import android.widget.BaseAdapter;
  13. import android.widget.ImageView;
  14. import android.widget.ListView;
  15. import android.widget.TextView;
  16. public class ImageAndTextListAdapter extends BaseAdapter {
  17. private LayoutInflater inflater;
  18. private ListView listView;
  19. private AsyncImageLoader asyncImageLoader;
  20. private List<ImageAndText> dataArray=new ArrayList<ImageAndText>();
  21. public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
  22. this.listView = listView;
  23. asyncImageLoader = new AsyncImageLoader();
  24. inflater = activity.getLayoutInflater();
  25. dataArray=imageAndTexts;
  26. }
  27. @Override
  28. public int getCount() {
  29. // TODO Auto-generated method stub
  30. return dataArray.size();
  31. }
  32. @Override
  33. public Object getItem(int position) {
  34. // TODO Auto-generated method stub
  35. if(position >= getCount()){
  36. return null;
  37. }
  38. return dataArray.get(position);
  39. }
  40. @Override
  41. public long getItemId(int position) {
  42. // TODO Auto-generated method stub
  43. return position;
  44. }
  45. //不需要ViewHolder版,直接将ImageAndText与XML资源关联起来
  46. public View getView(int position, View convertView, ViewGroup parent) {
  47. if (convertView == null) {
  48. convertView = inflater.inflate(R.layout.book_item_adapter, null);
  49. }
  50. convertView.setTag(position);
  51. ImageAndText imageAndText = (ImageAndText) getItem(position);
  52. String imageUrl = imageAndText.getImageUrl();
  53. TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle);
  54. // 将XML视图项与用户输入的URL和文本在绑定
  55. textView.setText(imageAndText.getText());//加载TEXT
  56. ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
  57. iv.setBackgroundResource(R.drawable.rc_item_bg);//在初始化时,先把背景图片设置成默认背景,
  58. //否则在下拉时会随机匹配背景,不美观
  59. asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
  60. @Override
  61. public void onImageLoad(Integer pos, Drawable drawable) {
  62. View view = listView.findViewWithTag(pos);
  63. if(view != null){
  64. ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
  65. iv.setBackgroundDrawable(drawable);
  66. }
  67. }
  68. //加载不成功的图片处理
  69. @Override
  70. public void onError(Integer pos) {
  71. View view = listView.findViewWithTag(pos);
  72. if(view != null){
  73. ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
  74. iv.setBackgroundResource(R.drawable.rc_item_bg);
  75. }
  76. }
  77. });
  78. return convertView;
  79. }
  80. }
package cn.wangmeng.test;

import java.util.ArrayList;
import java.util.List; import cn.wangmeng.test.AsyncImageLoader.ImageCallback; import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView; public class ImageAndTextListAdapter extends BaseAdapter { private LayoutInflater inflater;
private ListView listView;
private AsyncImageLoader asyncImageLoader; private List<ImageAndText> dataArray=new ArrayList<ImageAndText>(); public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) { this.listView = listView;
asyncImageLoader = new AsyncImageLoader();
inflater = activity.getLayoutInflater();
dataArray=imageAndTexts;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return dataArray.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
if(position >= getCount()){
return null;
}
return dataArray.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
} //不需要ViewHolder版,直接将ImageAndText与XML资源关联起来
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.book_item_adapter, null);
}
convertView.setTag(position); ImageAndText imageAndText = (ImageAndText) getItem(position);
String imageUrl = imageAndText.getImageUrl(); TextView textView = (TextView) convertView.findViewById(R.id.sItemTitle);
// 将XML视图项与用户输入的URL和文本在绑定
textView.setText(imageAndText.getText());//加载TEXT
ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
iv.setBackgroundResource(R.drawable.rc_item_bg);//在初始化时,先把背景图片设置成默认背景,
//否则在下拉时会随机匹配背景,不美观 asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
@Override
public void onImageLoad(Integer pos, Drawable drawable) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundDrawable(drawable);
}
}
//加载不成功的图片处理
@Override
public void onError(Integer pos) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundResource(R.drawable.rc_item_bg);
}
} });
return convertView;
}
}

我们着重看getView()函数 1、看这段:

  1. if (convertView == null) {
  2. convertView = inflater.inflate(R.layout.book_item_adapter, null);
  3. }
  4. convertView.setTag(position);
  5. ImageAndText imageAndText = (ImageAndText) getItem(position);
  6. String imageUrl = imageAndText.getImageUrl();
  7. TextView textView =  (TextView) convertView.findViewById(R.id.sItemTitle);
  8. // 将XML视图项与用户输入的URL和文本在绑定
  9. textView.setText(imageAndText.getText());//加载TEXT
  10. ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
  11. iv.setBackgroundResource(R.drawable.rc_item_bg);
if (convertView == null) {
convertView = inflater.inflate(R.layout.book_item_adapter, null);
}
convertView.setTag(position); ImageAndText imageAndText = (ImageAndText) getItem(position);
String imageUrl = imageAndText.getImageUrl(); TextView textView = (TextView) convertView.findViewById(R.id.sItemTitle);
// 将XML视图项与用户输入的URL和文本在绑定
textView.setText(imageAndText.getText());//加载TEXT
ImageView iv = (ImageView) convertView.findViewById(R.id.sItemIcon);
iv.setBackgroundResource(R.drawable.rc_item_bg);

这段代码没什么特别的就是将前面dataArray的信息与XML的元素项对应起来,并绑定,最关键的是下面这段,下面这个方法才是实现异步加载图片的关键:

  1. asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
  2. @Override
  3. public void onImageLoad(Integer pos, Drawable drawable) {
  4. View view = listView.findViewWithTag(pos);
  5. if(view != null){
  6. ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
  7. iv.setBackgroundDrawable(drawable);
  8. }
  9. }
  10. //加载不成功的图片处理
  11. @Override
  12. public void onError(Integer pos) {
  13. View view = listView.findViewWithTag(pos);
  14. if(view != null){
  15. ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
  16. iv.setBackgroundResource(R.drawable.rc_item_bg);
  17. }
  18. }
  19. });
asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
@Override
public void onImageLoad(Integer pos, Drawable drawable) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundDrawable(drawable);
}
}
//加载不成功的图片处理
@Override
public void onError(Integer pos) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundResource(R.drawable.rc_item_bg);
}
} });

这段代码的奇特之处在于,利用AsyncImageLoader类的实例(asyncImageLoader),调用方法loadDrawable()方法,就实现了加载后图像的绑定;好神奇,仔细看他是怎么做到的。这里先注意的有两点: (1)、传进去的参数,当前项的位置(position),当前图片的URL(imageUrl),一个名称为ImageCallback()接口函数;

(2)、ImageCallback()接口函数里的两个被重写的函数onImageLoad()和onError()

3、AsyncImageLoader.java

从上面的讲解也应该能猜到这个类,主要的功能就是加载图片,然后成功后更新UI;

先看全部代码,然后再逐步讲

  1. package cn.wangmeng.test;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.lang.ref.SoftReference;
  5. import java.net.URL;
  6. import java.util.HashMap;
  7. import android.graphics.drawable.Drawable;
  8. import android.os.Handler;
  9. public class AsyncImageLoader {
  10. final Handler handler = new Handler();
  11. private HashMap<String, SoftReference<Drawable>> imageCache;
  12. public AsyncImageLoader() {
  13. imageCache = new HashMap<String, SoftReference<Drawable>>();//图片缓存
  14. }
  15. // 回调函数
  16. public interface ImageCallback {
  17. public void onImageLoad(Integer t, Drawable drawable);
  18. public void onError(Integer t);
  19. }
  20. public Drawable loadDrawable(final Integer pos, final String imageUrl,
  21. final ImageCallback imageCallback) {
  22. new Thread() {
  23. @Override
  24. public void run() {
  25. LoadImg(pos, imageUrl, imageCallback);
  26. }
  27. }.start();
  28. return null;
  29. }// loadDrawable---end
  30. public void LoadImg(final Integer pos, final String imageUrl,
  31. final ImageCallback imageCallback) {
  32. // 首先判断是否在缓存中
  33. // 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现
  34. if (imageCache.containsKey(imageUrl)) {
  35. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  36. final Drawable drawable = softReference.get();
  37. if (drawable != null) {
  38. handler.post(new Runnable() {
  39. @Override
  40. public void run() {
  41. imageCallback.onImageLoad(pos, drawable);
  42. }
  43. });
  44. return;
  45. }
  46. }
  47. // 尝试从URL中加载
  48. try {
  49. final Drawable drawable = loadImageFromUrl(imageUrl);
  50. if (drawable != null) {
  51. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
  52. }
  53. handler.post(new Runnable() {
  54. @Override
  55. public void run() {
  56. imageCallback.onImageLoad(pos, drawable);
  57. }
  58. });
  59. } catch (IOException e) {
  60. handler.post(new Runnable() {
  61. @Override
  62. public void run() {
  63. imageCallback.onError(pos);
  64. }
  65. });
  66. e.printStackTrace();
  67. }
  68. }
  69. // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
  70. public static Drawable loadImageFromUrl(String url) throws IOException {
  71. URL m;
  72. InputStream i = null;
  73. m = new URL(url);
  74. i = (InputStream) m.getContent();
  75. Drawable d = Drawable.createFromStream(i, "src");
  76. return d;
  77. }
  78. }
package cn.wangmeng.test;

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.Handler; public class AsyncImageLoader {
final Handler handler = new Handler();
private HashMap<String, SoftReference<Drawable>> imageCache;
public AsyncImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();//图片缓存
} // 回调函数
public interface ImageCallback {
public void onImageLoad(Integer t, Drawable drawable);
public void onError(Integer t);
} public Drawable loadDrawable(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
new Thread() {
@Override
public void run() { LoadImg(pos, imageUrl, imageCallback); }
}.start();
return null;
}// loadDrawable---end public void LoadImg(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
// 首先判断是否在缓存中
// 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
final Drawable drawable = softReference.get();
if (drawable != null) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
return;
}
}
// 尝试从URL中加载
try {
final Drawable drawable = loadImageFromUrl(imageUrl);
if (drawable != null) {
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
}
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onError(pos);
}
});
e.printStackTrace();
} } // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
public static Drawable loadImageFromUrl(String url) throws IOException {
URL m;
InputStream i = null;
m = new URL(url);
i = (InputStream) m.getContent();
Drawable d = Drawable.createFromStream(i, "src");
return d;
} }

分别讲解 1、先看这段代码

  1. // 回调函数
  2. public interface ImageCallback {
  3. public void onImageLoad(Integer t, Drawable drawable);
  4. public void onError(Integer t);
  5. }
  6. public Drawable loadDrawable(final Integer pos, final String imageUrl,
  7. final ImageCallback imageCallback) {
  8. new Thread() {
  9. @Override
  10. public void run() {
  11. LoadImg(pos, imageUrl, imageCallback);
  12. }
  13. }.start();
  14. return null;
  15. }// loadDrawable---end
	// 回调函数
public interface ImageCallback {
public void onImageLoad(Integer t, Drawable drawable);
public void onError(Integer t);
} public Drawable loadDrawable(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
new Thread() {
@Override
public void run() { LoadImg(pos, imageUrl, imageCallback); }
}.start();
return null;
}// loadDrawable---end

(1)首先注意,刚才我们调用的loadDrawable()函数,里面初始化并运行了一个线程,而这个线程的里面只有一个函数LoadImg(),对于这个函数下面我们具体讲,它的主要功能就是加载图片,然后更新UI (2)上面也看出了ImageCallback是一个接口,而里面的两个函数onImageLoad()和onError()在这里是没有具体实现的,那在哪里实现呢,当然是我们上面的ImageAndTextListAdapter.java里面了,等下我们具体会再讲。

再往下看

  1. // 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
  2. public static Drawable loadImageFromUrl(String url) throws IOException {
  3. URL m;
  4. InputStream i = null;
  5. m = new URL(url);
  6. i = (InputStream) m.getContent();
  7. Drawable d = Drawable.createFromStream(i, "src");
  8. return d;
  9. }
  10. public void LoadImg(final Integer pos, final String imageUrl,
  11. final ImageCallback imageCallback) {
  12. // 首先判断是否在缓存中
  13. // 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现
  14. if (imageCache.containsKey(imageUrl)) {
  15. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  16. final Drawable drawable = softReference.get();
  17. if (drawable != null) {
  18. handler.post(new Runnable() {
  19. @Override
  20. public void run() {
  21. imageCallback.onImageLoad(pos, drawable);
  22. }
  23. });
  24. return;
  25. }
  26. }
  27. // 尝试从URL中加载
  28. try {
  29. final Drawable drawable = loadImageFromUrl(imageUrl);
  30. if (drawable != null) {
  31. imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
  32. }
  33. handler.post(new Runnable() {
  34. @Override
  35. public void run() {
  36. imageCallback.onImageLoad(pos, drawable);
  37. }
  38. });
  39. } catch (IOException e) {
  40. handler.post(new Runnable() {
  41. @Override
  42. public void run() {
  43. imageCallback.onError(pos);
  44. }
  45. });
  46. e.printStackTrace();
  47. }
  48. }
	// 根据URL加载图片,如果出现错误throws IOException式的错误,以便在LoadImg中捕获,执行OnError()函数
public static Drawable loadImageFromUrl(String url) throws IOException {
URL m;
InputStream i = null;
m = new URL(url);
i = (InputStream) m.getContent();
Drawable d = Drawable.createFromStream(i, "src");
return d;
} public void LoadImg(final Integer pos, final String imageUrl,
final ImageCallback imageCallback) {
// 首先判断是否在缓存中
// 但有个问题是:ImageCache可能会越来越大,以至用户内存用光,所以要用SoftReference(弱引用)来实现
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
final Drawable drawable = softReference.get();
if (drawable != null) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
return;
}
}
// 尝试从URL中加载
try {
final Drawable drawable = loadImageFromUrl(imageUrl);
if (drawable != null) {
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
}
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onError(pos);
}
});
e.printStackTrace();
} }

(1)、loadImageFromUrl()函数,就是根据URL到网上加载图片,然后返回图片流Drawable类型变量 (2)、对于LoadImg()我们再拆一下,先看如何在缓存中加载

  1. if (imageCache.containsKey(imageUrl)) {
  2. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  3. final Drawable drawable = softReference.get();
  4. if (drawable != null) {
  5. handler.post(new Runnable() {
  6. @Override
  7. public void run() {
  8. imageCallback.onImageLoad(pos, drawable);
  9. }
  10. });
  11. return;
  12. }
  13. }
		if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl);
final Drawable drawable = softReference.get();
if (drawable != null) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
return;
}
}

注意:

1、在这里就已经得到了图像

  1. SoftReference<Drawable> softReference = imageCache.get(imageUrl);
  2. final Drawable drawable = softReference.get();
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);
final Drawable drawable = softReference.get();

2、得到图像之后就到了这段代码:

  1. if (drawable != null) {
  2. handler.post(new Runnable() {
  3. @Override
  4. public void run() {
  5. imageCallback.onImageLoad(pos, drawable);
  6. }
  7. });
  8. return;
  9. }
			if (drawable != null) {
handler.post(new Runnable() {
@Override
public void run() {
imageCallback.onImageLoad(pos, drawable);
}
});
return;
}

当我们得到图像之后,调用imageCallback.onImageLoad(pos, drawable);来更新UI,由于我们再回来看看ImageAndTextListAdapter.java中的代码

  1. asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
  2. @Override
  3. public void onImageLoad(Integer pos, Drawable drawable) {
  4. View view = listView.findViewWithTag(pos);
  5. if(view != null){
  6. ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
  7. iv.setBackgroundDrawable(drawable);
  8. }
  9. }
  10. });
asyncImageLoader.loadDrawable(position,imageUrl, new ImageCallback() {
@Override
public void onImageLoad(Integer pos, Drawable drawable) {
View view = listView.findViewWithTag(pos);
if(view != null){
ImageView iv = (ImageView) view.findViewById(R.id.sItemIcon);
iv.setBackgroundDrawable(drawable);
}
} });

看到了吧,就是把得到的drawable与加载到UI中!!!!这就实现了回调

OK,就到这吧,OnError()的原理一样,只不过是对程序没有加载到图片时应该怎么处理,其实就是当没有加载到图片时就是默认图片代替。
下面给出源码:http://download.csdn.net/detail/harvic880925/6802241(不要分,仅供分享)

请大家尊重作者板权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/17766027 ,谢谢!

listview中getview异步加载网络图片的更多相关文章

  1. wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)

    wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...

  2. android官方开源的高性能异步加载网络图片的Gridview例子

    这个是我在安卓安卓巴士上看到的资料,放到这儿共享下.这个例子android官方提供的,其中讲解了如何异步加载网络图片,以及在gridview中高效率的显示图片此代码很好的解决了加载大量图片时,报OOM ...

  3. Libgdx实现异步加载网络图片并保存到SD卡或者data/data目录下边

    Libgdx实现异步加载网络图片并保存到SD卡或者data/data目录下边,当本地有图片的时候,直接从本地读取图片,如果本地没有图片,将从服务器异步加载图片 package com.example. ...

  4. (BUG已修改,最优化)安卓ListView异步加载网络图片与缓存软引用图片,线程池,只加载当前屏之说明

    原文:http://blog.csdn.net/java_jh/article/details/20068915 迟点出更新的.这个还有BUG.因为软引应不给力了.2.3之后 前几天的原文有一个线程管 ...

  5. cocos2dx lua中异步加载网络图片,可用于显示微信头像

    最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能 ...

  6. Android批量图片加载经典系列——采用二级缓存、异步加载网络图片

    一.问题描述 Android应用中经常涉及从网络中加载大量图片,为提升加载速度和效率,减少网络流量都会采用二级缓存和异步加载机制,所谓二级缓存就是通过先从内存中获取.再从文件中获取,最后才会访问网络. ...

  7. Android进阶:ListView性能优化异步加载图片 使滑动效果流畅

    ListView 是一种可以显示一系列项目并能进行滚动显示的 View,每一行的Item可能包含复杂的结构,可能会从网络上获取icon等的一些图标信息,就现在的网络速度要想保持ListView运行的很 ...

  8. UIImageView异步加载网络图片

    在iOS开发过程中,经常会遇到使用UIImageView展现来自网络的图片的情况,最简单的做法如下: 去下载https://github.com/rs/SDWebImage放进你的工程里,加入头文件# ...

  9. ListView与GridView异步加载图片

    原理很简单,主要是用到了回调方法,下面是异步加载图片的类 <span style="font-size:16px;">package com.xxx.xxx; impo ...

随机推荐

  1. hihocoder#1054 : 滑动解锁(深度优先搜索)

    描述 滑动解锁是智能手机一项常用的功能.你需要在3x3的点阵上,从任意一个点开始,反复移动到一个尚未经过的"相邻"的点.这些划过的点所组成的有向折线,如果与预设的折线在图案.方向上 ...

  2. MyElcipse之问题小结

    运行MyEclipse时,遇到这一错误提示: An internal error occurred during: "Launching chat on MyEclipse Tomcat & ...

  3. sql 查询包含字符的数量统计

    );); SELECT @word = 'I do not like to get the news, because there has never been an era when so many ...

  4. 关于servlet是在什么时候初始化的个人总结

    今天无意中看到一个博主的总结,总结的是servlet是在什么时候初始化的,并且附上了实例.但是由于那位博主的实例有问题,所以总结的也有误.这里我把我的体会写下来,分享给大家. java代码: @Ove ...

  5. 检测URL地址是否有响应

    今天突然出来了一个问题,URL地址调用导致程序卡死(原因是服务挂了,磁盘坏了) 然后想到了,再调用URL地址前先判断下地址是否有响应,这样不就可以解决问题了吗? C# 代码: /// <summ ...

  6. UI4_UIStepper与UIProgressView

    // // ViewController.m // UI4_UIStepper与UIProgressView // // Created by zhangxueming on 15/7/7. // C ...

  7. 基于python yield机制的异步操作同步化编程模型

    又一个milestone即将结束,有了些许的时间总结研发过程中的点滴心得,今天总结下如何在编写python代码时对异步操作进行同步化模拟,从而提高代码的可读性和可扩展性. 游戏引擎一般都采用分布式框架 ...

  8. (转)MongoDB分片实战 集群搭建

    环境准备 Linux环境 主机 OS 备注 192.168.32.13 CentOS6.3 64位 普通PC 192.168.71.43 CentOS6.2 64位 服务器,NUMA CPU架构 Mo ...

  9. 判断Featureclass的类型

    一个Featureclass可以是Shapefile Feature Class.Personal Geodatabase Feature Class.File Geodatabase Feature ...

  10. [翻译.每月一译.每日一段]Exploring Fonts with DirectWrite and Modern C++

    Windows with C++ Exploring Fonts with DirectWrite and Modern C++ Kenny Kerr DirectWrite is an incred ...