我有一個自定義的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