我有一个自定义的ListView
,我显示了一些从本地数据库检索到的武器。我总共有88行,每行调用一个文本和一个图像,每次调用getView()
。 ListView
滞后,而滚动速度快,垃圾收集器疯狂,每秒删除一些1M对象。我不明白为什么。ListView性能很慢
在我发布我的Adapter
实现之前,有关如何设置图像的一些说明。我的武器类只是一个数据的持有者和获取者。这是多么的名字和图像的数据库中被创建时,收到设定(是它似乎很奇怪,但所有其他解决方案的工作,甚至更慢):
private Weapon buildWeapon(Cursor cursor) {
Weapon w = new Weapon();
w.setId(cursor.getLong(0));
w.setName(cursor.getString(1));
w.setImage(Constants.ALL_WEAPON_IMAGES[(int) cursor.getLong(0)-1]);
return w;
}
所以我有一个包含在所有武器图像的Array
形式为R.drawable.somegun
。数据结构的实现方式使ID-1始终指向我的Array
中的正确可绘制引用。武器类中的图像字段是Integer
。现在你有一个想法,我getImage()
方法是如何工作的,并在下面进入我的Adapter
:
public class Weapon_Adapter extends BaseAdapter {
private List<Weapon> items;
private LayoutInflater inflater = null;
private WeaponHolder weaponHolder;
private Weapon wp;
static class WeaponHolder {
public TextView text;
public ImageView image;
}
// Context and all weapons of specified class are passed here
public Weapon_Adapter(List<Weapon> items, Context c) {
this.items = (List<Weapon>) items;
inflater = LayoutInflater.from(c);
Log.d("Adapter:", "Adapter created");
}
@Override
public int getCount() {
return items.size();
}
@Override
public Weapon getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
wp = (Weapon) getItem(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.category_row, null);
weaponHolder = new WeaponHolder();
weaponHolder.text = (TextView) convertView
.findViewById(R.id.tvCatText);
weaponHolder.image = (ImageView) convertView
.findViewById(R.id.imgCatImage);
convertView.setTag(weaponHolder);
}
weaponHolder = (WeaponHolder) convertView.getTag();
weaponHolder.text.setText(wp.getName());
weaponHolder.image.setImageResource(wp.getImage());
// weaponHolder.image.setImageResource(R.drawable.ak74m);
return convertView;
}}
现在奇怪的事情:使用outcommented行静态设置相同的图像的所有项目删除即使不是所有的滞后和GC叫一次!我没有明白它.. wp.getImage()
返回完全相同的东西,每个武器只有R.drawable.name
是不同的。但是GC在滚动时删除了大量的对象和时间滞后。任何想法我做错了什么?
UPDATE
我搬到设置图像的AsyncTask
现在滞后了:
public class AsyncImageSetter extends AsyncTask<Void, Void, Void> {
private ImageView img;
private int image_resId;
private Bitmap bmp;
private Context c;
public AsyncImageSetter(Context c, ImageView img, int image_ResId, Bitmap bmp) {
this.img = img;
this.image_resId = image_ResId;
this.bmp = bmp;
this.c = c;
}
@Override
protected Void doInBackground(Void... params) {
bmp = BitmapFactory.decodeResource(c.getResources(), image_resId);
return null;
}
@Override
protected void onPostExecute(Void result) {
img.setImageBitmap(bmp);
bmp = null;
super.onPostExecute(result);
}
}
然而,滚动整个GC时仍称像疯了似的RAM消耗增加上下列出。现在的问题是:如何优化图像回收以避免RAM使用量增加?
使用延迟加载技术来加载图像。检查此链接http://stackoverflow.com/questions/16789676/caching-images-and-displaying/16978285#16978285可能也会帮助你,如果图像很大尝试缩小图像 – Raghunandan
我读过关于它,它是适合从应用程序之外的地方加载一堆数据。我的图片数量非常有限,全部来自可绘制文件夹。我试图找出为什么outcommented行工作的很快,而我的getImage()方法几乎相同会导致List滞后。图像不是很大,可以通过ImageView的ScaleType参数来缩放 – Droidman
有多大每个图像? – m0skit0