【发布时间】:2016-09-08 07:06:33
【问题描述】:
我正在使用这个ArrayAdapter 异步加载缩略图
public class CourierArrayAdapter extends ArrayAdapter<Courier> {
private Map<String, Bitmap> bitmaps = new HashMap<>();
private static class ViewHolder{
TextView txtViewName;
TextView txtViewNumber;
CircleImageView imageViewPic;
int position;
}
public CourierArrayAdapter(Context context, List<Courier> requests) {
super(context, -1, requests);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
Courier request = getItem(position);
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater layoutInflater = LayoutInflater.from(getContext());
convertView = layoutInflater.inflate(R.layout.list_item_courier, parent, false);
viewHolder.txtViewName = (TextView) convertView.findViewById(R.id.textView_list_item_courier_name);
viewHolder.txtViewNumber = (TextView) convertView.findViewById(R.id.textView_list_item_courier_number);
viewHolder.imageViewPic = (CircleImageView) convertView.findViewById(R.id.imageView_list_item_courier_pic);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.txtViewName.setText(request.name);
viewHolder.txtViewNumber.setText(request.number);
viewHolder.position = position;
if (bitmaps.containsKey(request.picURL)) {
viewHolder.imageViewPic.setImageBitmap(bitmaps.get(request.picURL));
}
else
new LoadImageTask(position, viewHolder).execute(request.picURL);
return convertView;
}
private class LoadImageTask extends AsyncTask<String, Void, Bitmap> {
private int mPosition;
private ViewHolder mViewHolder;
public LoadImageTask(int position, ViewHolder holder) {
this.mPosition = position;
this.mViewHolder = holder;
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap = null;
HttpURLConnection connection = null;
try {
URL url = new URL(params[0]); // create URL for image
connection = (HttpURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
try {
bitmap = BitmapFactory.decodeStream(inputStream);
bitmaps.put(params[0], bitmap);
} catch (Exception e) {
e.printStackTrace();
}
finally {
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
connection.disconnect(); // close the HttpURLConnection
}
return bitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
if (mViewHolder.position == mPosition)
mViewHolder.imageViewPic.setImageBitmap(bitmap);
}
}
}
如您所见,我使用picURL 属性加载这些图像,并使用私有AsyncTask 类加载它们。问题是我收到OutOfMemoryException 一条错误消息:
FATAL EXCEPTION: AsyncTask #3
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 37602252 byte allocation with 16776720 free bytes and 29MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:863)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:839)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:877)
at net.faraznet.provider.arrayadapters.CourierArrayAdapter$LoadImageTask.doInBackground(CourierArrayAdapter.java:99)
at net.faraznet.provider.arrayadapters.CourierArrayAdapter$LoadImageTask.doInBackground(CourierArrayAdapter.java:76)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
图像有点大,如果可能的话,我在将它们加载到内存之前调整它们的大小不是问题,但问题是我不知道如何完成此任务或任何其他解决方案我的问题
【问题讨论】:
-
使用Picasso 加载图片。它很容易实现并且会处理 OOM :)
-
你可以使用 Glide 而不是 Picasso。 Glide 在性能和内存管理方面效率更高。检查这个inthecheesefactory.com/blog/…
-
@SripadRaj Glide 比毕加索好得多。您可以查看我指定的链接进行性能比较
标签: android listview android-asynctask out-of-memory