我正在尝试使用列表视图上的自定义适配器从网址加载图片。我收到内存不足错误。我正在使用下面链接中的代码
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
package com.example.video;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
String url;
private final WeakReference<ImageView> imageViewReference;
public BitmapDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
url=params[0];
return downloadBitmap(url);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
// Change bitmap only if this process is still associated with it
if (this == bitmapDownloaderTask) {
imageView.setImageBitmap(bitmap);
}
}
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
static class DownloadedDrawable extends ColorDrawable {
private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;
public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
super(Color.BLACK);
bitmapDownloaderTaskReference =
new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
}
public BitmapDownloaderTask getBitmapDownloaderTask() {
return bitmapDownloaderTaskReference.get();
}
}
static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or IllegalStateException
getRequest.abort();
Log.d("ImageDownloader", "Error while retrieving bitmap from "+url+""+e.toString());
} finally {
if (client != null) {
client.close();
}
}
return null;
}
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 byt = read();
if (byt < 0) {
break; // we reached EOF
} else {
bytesSkipped = 1; // we read one byte
}
}
totalBytesSkipped += bytesSkipped;
}
return totalBytesSkipped;
}
}
}
我的自定义适配器:
package com.example.video;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.records.MyRecord;
import com.example.video.BitmapDownloaderTask.DownloadedDrawable;
//Showing all the text and images on a list view
public class CustomAdapter extends ArrayAdapter{
int size=1;
Context context;
ArrayList<MyRecord> Name;
Bitmap bitmap;
Activity a;
Bitmap mPlaceHolderBitmap;
public CustomAdapter(Context c, ArrayList<MyRecord> Name,Activity a) {
super(c, R.layout.list_row,Name);
this.context=c;
this.Name=Name;
this.a=a;
}
public View getView(int position, View convertView, ViewGroup parent){
LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row=inflater.inflate(R.layout.list_row, parent,false);
TextView title=(TextView) row.findViewById(R.id.textView1);
title.setText(""+Name.get(position).getTitle());
title.setTypeface(Splash.tf);
TextView author=(TextView) row.findViewById(R.id.textAuthor);
author.setText(""+Name.get(position).getTitle());
author.setTypeface(Splash.tf);
TextView views=(TextView) row.findViewById(R.id.textViews);
views.setText(""+Name.get(position).getViews()+"views");
views.setTypeface(Splash.tf);
TextView date=(TextView) row.findViewById(R.id.textDatePublished);
date.setText(""+Name.get(position).getDate_Published());
date.setTypeface(Splash.tf);
ImageView i=(ImageView) row.findViewById(R.id.imageview1);
String url=Name.get(position).getImgUri();
String imageUrl="http://64.111.243.324/vod/"+url;
// i.setTag(imageUrl);
//running an asynchronous task in the background to load images from url
// new MyTask().execute(i);
ImageDownloader id=new ImageDownloader();
id.download(imageUrl, i);
return row;
}
}
Image Downloader Class:
package com.example.video;
import com.example.video.BitmapDownloaderTask.DownloadedDrawable;
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
public class ImageDownloader {
public void download(String url, ImageView imageView) {
if (cancelPotentialDownload(url, imageView)) {
BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
imageView.setImageDrawable(downloadedDrawable);
task.execute(url);
}
}
private static boolean cancelPotentialDownload(String url, ImageView imageView) {
BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
if (bitmapDownloaderTask != null) {
String bitmapUrl = bitmapDownloaderTask.url;
if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
bitmapDownloaderTask.cancel(true);
} else {
// The same URL is already being downloaded.
return false;
}
}
return true;
}
private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
if (imageView != null) {
Drawable drawable = imageView.getDrawable();
if (drawable instanceof DownloadedDrawable) {
DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
return downloadedDrawable.getBitmapDownloaderTask();
}
}
return null;
}
}
答案 0 :(得分:0)
删除AsyncTask并从适配器使用picasso api http://square.github.io/picasso。
答案 1 :(得分:0)
如果不使用'convertView'参数,你会过多地夸大视图,这也可能导致性能问题。通过执行以下操作解决此问题:
View row = convertView != null ? convertView : inflater.inflate(R.layout.list_row, parent,false);
关于图像缓存,请不要重新发明轮子,而是专注于应用程序的核心逻辑。只需使用已知且可靠的Cache&amp; amp;框架。获取图像,例如Picasso。
您的代码将被缩减,在您的getView()方法中,您只需使用它:
Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);