我在ListActivity中有一个扩展的BaseAdapter:
private static class RequestAdapter extends BaseAdapter {
并在其中定义了一些处理程序和runnable
// Need handler for callbacks to the UI thread
final Handler mHandler = new Handler();
// Create runnable for posting
final Runnable mUpdateResults = new Runnable() {
public void run() {
loadAvatar();
}
};
protected static void loadAvatar() {
// TODO Auto-generated method stub
//ava.setImageBitmap(getImageBitmap("URL"+pic));
buddyIcon.setImageBitmap(avatar);
}
在Adapter的getView函数中,我得到的视图如下:
if (convertView == null) {
convertView = mInflater.inflate(R.layout.messageitem, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.username);
holder.date = (TextView) convertView.findViewById(R.id.dateValue);
holder.time = (TextView) convertView.findViewById(R.id.timeValue);
holder.notType = (TextView) convertView.findViewById(R.id.notType);
holder.newMsg = (ImageView) convertView.findViewById(R.id.newMsg);
holder.realUsername = (TextView) convertView.findViewById(R.id.realUsername);
holder.replied = (ImageView) convertView.findViewById(R.id.replied);
holder.msgID = (TextView) convertView.findViewById(R.id.msgID_fr);
holder.avatar = (ImageView) convertView.findViewById(R.id.buddyIcon);
holder.msgPreview = (TextView) convertView.findViewById(R.id.msgPreview);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
并且图像以这种方式加载:
Thread sepThread = new Thread() {
public void run() {
String ava;
ava = request[8].replace(".", "_micro.");
Log.e("ava thread",ava+", username: "+request[0]);
avatar = getImageBitmap(URL+ava);
buddyIcon = holder.avatar;
mHandler.post(mUpdateResults);
//holder.avatar.setImageBitmap(getImageBitmap(URL+ava));
}
};
sepThread.start();
现在,我遇到的问题是如果有更多的项目需要显示相同的图片,那么并非所有这些图片都会显示出来。当您向上和向下滚动列表时,您最终可能会填满所有这些内容。
当我尝试注释掉的行(holder.avatar.setImageBitmap ...)时,应用程序有时强制关闭“只有创建视图的线程可以请求...”。但有时候只是。
知道如何解决这个问题吗?两种选择。
答案 0 :(得分:1)
因此,您不应该尝试将图像添加到另一个线程中的视图中。我的建议是使用像这样的AsyncTask:
class GetImageTask extends AsyncTask<String, int[], Bitmap> {
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
// Get your image bitmap here
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmapResult) {
super.onPostExecute(bitmapResult);
// Add your image to your view
holder.avatar.setImageBitmap(bitmapResult);
}
}
您调用AsyncTask,如:
new GetImageTask().execute(param1, param2, etc);
有关AsyncTask的更多信息,请查看: http://developer.android.com/reference/android/os/AsyncTask.html
答案 1 :(得分:1)
当调用getView时,你有一个头像ImageView。您应该将此实例传递给sepThread,sepThread应将此实例传递给mUpdateResults。这样,位图将完全显示给下载的ImageView。否则,位图会显示给某个不正确的budddyIcon实例。您的线程正在下载图像一段时间,当它准备好时,budddyIcon引用另一个ImageView,因为已经调用了另一个getView。
看起来应该是这样的:
public View getView(...){
//skip
(new SepThread(holder.avatar)).start();
}
public class SepThread extends Thread() {
ImageView imageView;
public SepThread(ImageVIew iv){
imageView=iv;
}
public void run() {
//skip
Bitmap avatar = getImageBitmap(URL+ava);
mHandler.post(new UpdateResults(imageView, avatar));
}
};
class UpdateResults extends Runnable() {
ImageView imageView;
Bitmap bitmap;
public UpdateResults(ImageView iv, Bitmap b){
imageView=iv;
bitmap=b;
}
public void run() {
loadAvatar(imageView, bitmap);
}
};
protected static void loadAvatar(ImageView iv, Bitmap b) {
iv.setImageBitmap(b);
}
当然,你应该知道回收的convertViews,如上所述。
我做了一个完整的LazyList示例并发布了源代码,也可能有用Lazy load of images in ListView。
答案 2 :(得分:1)
这是一个很棒的图书馆工作人员从网上下载/缓存图像 https://github.com/koush/UrlImageViewHelper
只需输入imageview和url即可完成=)