我正在开发一个使用staggered gridview的应用程序我遇到了严重的性能问题,因为在加载了6,7个项目后,滚动非常滞后,我得到的时间减少了一半:OutOfMemoryError at“android.graphics.BitmapFactory .nativeDecodeStream(Native Method)“
这是我的适配器(我正在使用持有人模式):
package ngapps.socialbackground;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import ngapps.socialbackground.Util.ImageDownloaderTask;
/**
* Created by Naor on 02/09/2014.
*/
public class ItemAdapter extends BaseAdapter {
ArrayList<ImageItem> imageItemArrayList = new ArrayList<ImageItem>();
Context context;
static class ViewHolder {
public TextView textView;
public ImageView imageView;
ViewHolder(View base) {
textView = (TextView) base.findViewById(R.id.textView);
imageView = (ImageView) base.findViewById(R.id.imageView);
}
}
public ItemAdapter(Context context){
this.context = context;
}
@Override
public int getCount() {
return imageItemArrayList.size();
}
@Override
public Object getItem(int position) {
return imageItemArrayList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public void addItem(ImageItem imageItem){
imageItemArrayList.add(imageItem);
notifyDataSetChanged();
}
public void addItems(List<ImageItem> items) {
imageItemArrayList.addAll(items);
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (convertView == null){
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = inflater.inflate(R.layout.item_layout,null);
holder = new ViewHolder(v);
v.setTag(holder);
} else {
holder = (ViewHolder) v.getTag();
}
ImageItem curImageItem = imageItemArrayList.get(position);
holder.textView.setText(curImageItem.getText());
if (curImageItem.getPreviewBitmap() != null)
holder.imageView.setImageBitmap(curImageItem.getPreviewBitmap());
else
new ImageDownloaderTask(holder.imageView, curImageItem).execute(curImageItem.getImageURL());
return v;
}
}
这是ImageDownloaderTask:
package ngapps.socialbackground.Util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import java.io.InputStream;
import ngapps.socialbackground.ImageItem;
/**
* Created by Naor on 04/09/2014.
*/
public class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
ImageItem imageItem;
public ImageDownloaderTask(ImageView bmImage, ImageItem imageItem) {
this.bmImage = bmImage;
this.imageItem = imageItem;
}
protected Bitmap doInBackground(String... urls) {
String url = urls[0];
Bitmap mIcon = null;
try {
InputStream in = new java.net.URL(url).openStream();
mIcon = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
}
return mIcon;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
imageItem.setPreviewBitmap(result);
}
}
图像宽约160像素, 我已经验证了持有者模式是有效的,我只创建了有限数量的视图,并且在图像下载完成后没有创建新的ImageDownloaderTask
并且在滚动完所有内容后仍然落后
是什么伤害了我的表现?
答案 0 :(得分:0)
您的代码存在内存泄漏,我发布了解决方案并提示处理此问题here。可能OutOfMemoryException发生在代码的这一行:
InputStream in = new java.net.URL(url).openStream();
mIcon = BitmapFactory.decodeStream(in);