我和这个家伙有同样的问题 Listview shows wrong images
我看到了我必须缓存它的解决方案。但在我的缓存中,我不确定如何应用解决方案中给出的缓存。我一直收到错误。
我怀疑这是我遇到问题的部分:
holder.icon.setImageBitmap(bitmapList[position]);
//loadImageBitmap(mObjects.get(position), position);
//onBitmapLoaded(position, holder.mTask.myBitmap());
以下是代码。 Adapter.java 公共类适配器扩展BaseAdapter {
private static final String TAG = "Adapter";
private Activity mActivity;
public ArrayList<Data> mObjects;
static class ViewHolder {
ImageView icon;
TextView title;
WebView newimage;
DownloadImageTask mTask;
public void setOnClickListener(OnItemClickListener onItemClickListener) {
// TODO Auto-generated method stub
}
}
private Bitmap[] bitmapList;
private Bitmap bitmapPlaceholder;
private void initBitmapListWithPlaceholders(){
// call this whenever the list size changes
// you can also use a list or a map or whatever so you
// don't need to drop all the previously loaded bitmap whenever
// the list contents are modified
int count = getCount();
bitmapList = new Bitmap[count];
for(int i=0;i<count;i++){
bitmapList[i]=bitmapPlaceholder;
}
}
private void onBitmapLoaded(int position, Bitmap bmp){
// this is your callback when the load async is done
bitmapList[position] = bmp;
}
public Adapter(Activity activity, ArrayList<Data> mObjects) {
this.mActivity = (Activity) activity;
this.mObjects = mObjects;
}
public void setObjects(ArrayList<Data> mObjects) {
this.mObjects = mObjects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Data item = mObjects.get(position);
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = mActivity.getLayoutInflater();
rowView = inflater.inflate(R.layout.item, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.icon = (ImageView) rowView.findViewById(R.id.image);
viewHolder.title = (TextView) rowView.findViewById(R.id.title);
viewHolder.newimage =(WebView)rowView.findViewById(R.id.newimage);
rowView.setTag(viewHolder);
}
ViewHolder holder = (ViewHolder) rowView.getTag();
holder.title.setText(item.getmTitle());
//String html = " <html><head></head><body><p font-size='8px'>" + item.getmImageUrl() + "</p><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>";
String html = " <html><head></head><body><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>";
holder.newimage.loadData(html, "text/html", "utf-8");
holder.newimage.setFocusable(false);
holder.newimage.setClickable(false);
holder.setOnClickListener(new OnItemClickListener() {
private Object title;
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
//Toast.makeText(Adapter.this,"Button is clicked", Toast.LENGTH_LONG).show();
Log.e("log_tag",this.title.toString() + " clicked");
}
});
//holder.icon.setBackgroundResource(R.drawable.ic_launcher);
holder.mTask = new DownloadImageTask(item.getmImageUrl(), holder.icon);
holder.icon.setImageBitmap(bitmapList[position]);
//loadImageBitmap(mObjects.get(position), position);
//onBitmapLoaded(position, holder.mTask.myBitmap());
if (!holder.mTask.isCancelled()) {
holder.mTask.execute();
}
return rowView;
}
@Override
public int getCount() {
return (this.mObjects.size());
}
@Override
public Object getItem(int position) {
return (this.mObjects.get(position));
}
@Override
public long getItemId(int position) {
return (position);
}
public AbsListView.RecyclerListener mRecyclerListener = new RecyclerListener( ){
public void onMovedToScrapHeap(View view) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
DownloadImageTask imagetask = viewHolder.mTask;
if (imagetask != null) {
imagetask.cancel(true);
}
}
};
public void setOnClickListener(OnItemClickListener onItemClickListener) {
// TODO Auto-generated method stub
}
DownloadImageTask.java
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;
public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
public Bitmap g;
private String mUrl;
private ImageView mImageView = null;
public DownloadImageTask(String Url, ImageView imageView) {
mUrl = Url;
this.mImageView = imageView;
}
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (result != null) {
mImageView.setImageBitmap(result);
//result.recycle();
}
}
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = getBitmap(mUrl);
return bitmap;
}
public Bitmap getBitmap(String imageUrl) {
Bitmap mBitmap = null;
try {
/*URL newurl = new URL(imageUrl);
mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */
//mImageView.setImageBitmap(mBitmap);
/*
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream is = conn.getInputStream();
mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/
InputStream in = new java.net.URL(imageUrl).openStream();
mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in));
//mBitmap.recycle();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.g = mBitmap;
return mBitmap;
}
public Bitmap myBitmap() {
Bitmap fg;
fg = (Bitmap) g;
return fg;
}
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
修改
我修改了DownloadImageTask.java,按照以下代码进行一些缓存:https://stackoverflow.com/a/7730547
但我似乎在这方面有问题:
if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) {
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
}
由于if ...行,应用程序总是崩溃。这令人非常沮丧。我需要帮助。请帮我。下面是修改后的DownloadImageTask.Java
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.view.View;
import android.widget.ImageView;
public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> {
public Bitmap g;
private String mUrl;
private ImageView mImageView = null;
public DownloadImageTask(String Url, ImageView imageView) {
mUrl = Url;
this.mImageView = imageView;
}
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
/*
if (result != null) {
mImageView.setImageBitmap(result);
}
*/
if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) {
/* The path is not same. This means that this
image view is handled by some other async task.
We don't do anything and return. */
return;
}
if(result != null && mImageView != null){
mImageView.setVisibility(View.VISIBLE);
mImageView.setImageBitmap(result);
mImageView.setTag(this.mUrl);
}else{
mImageView.setVisibility(View.GONE);
}
}
protected Bitmap doInBackground(Void... params) {
Bitmap bitmap = getBitmap(mUrl);
return bitmap;
}
public Bitmap getBitmap(String imageUrl) {
Bitmap mBitmap = null;
try {
/*URL newurl = new URL(imageUrl);
mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */
//mImageView.setImageBitmap(mBitmap);
/*
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
InputStream is = conn.getInputStream();
mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/
InputStream in = new java.net.URL(imageUrl).openStream();
mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in));
//this.mImageView.setTag(this.mUrl);
//mBitmap.recycle();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
this.g = mBitmap;
return mBitmap;
}
public Bitmap myBitmap() {
Bitmap fg;
fg = (Bitmap) g;
return fg;
}
static class FlushedInputStream extends FilterInputStream {
public FlushedInputStream(InputStream inputStream) {
super(inputStream);
}
@Override
public long skip(long n) throws IOException {
long totalBytesSkipped = 0L;
while (totalBytesSkipped < n) {
long bytesSkipped = in.skip(n - totalBytesSkipped);
if (bytesSkipped == 0L) {
int b = read();
if (b < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
答案 0 :(得分:0)
而不是使用AsyncTask
手动实现此操作,您可以使用缓存库。
Android查询非常好:http://code.google.com/p/android-query/
要使用Android Query加载图像,您可以在ListView适配器的getView
方法中使用以下代码:
AQuery _aq = new AQuery(mActivity);
_aq.id(R.id.icon).image("IMAGE_URI_TO_LOAD");
这应该取代holder.icon.setImageBitmap(bitmapList[position]);
来电。
这将加载,缓存并在imageview中显示来自Uri的图像。如果图像已经缓存,则会从缓存中自动加载。
有关如何使用此库进行图像加载的详细信息,请访问以下网址:http://code.google.com/p/android-query/wiki/ImageLoading