基本上我有一个gridview,我在其中显示我的产品(从10或20到1K +项目),每个项目都有几个自定义文本视图和一个Imageview。
我使用ViewHolder模式和Picasso库来异步加载图像。我没有显示项目,速度或任何问题,所以我认为我的getview功能非常好,虽然我有一个主要问题,即滚动网格视图,上下,我的记忆,这是安全的。监视器仅显示增加当然增量率取决于项目视图内容,例如当我评论图像加载部分时,速率降低。
我猜是生成的视图总是停留在内存中,而某些东西会阻止它们被GC收集。 虽然有时候,当我慢慢地滚动时GC会收集并且内存自由,但是快速滚动总会导致OOM迟早。
我的主要问题是,如果我有内存泄漏?!因为gc有时会工作(缓慢的scrlling),有时会让应用程序崩溃与OOM异常。
显然我希望能够找到我的问题,并提前感谢每一点帮助。
承载Gridview的片段布局的xml:
<GridView
android:id="@+id/gv_Main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:animationCache="false"
android:clickable="true"
android:descendantFocusability="beforeDescendants"
android:gravity="center"
android:scrollingCache="false"
android:verticalSpacing="10dp"
/>
我的适配器(这扩展了CursorAdapter,虽然我也有完全相同的问题,但是whit baseadapter也是如此):
public class ShygunInventoryGridCursorAdapter extends CursorAdapter {
private Context mContext;
private Cursor cursor;
private int numColumns;
private int listItemId, listItemNoImageId, gridItemId;
private String[] type;
private String[] columnTitle;
private int[] viewId;
private String textTemp;
private CyberSetting cyberSetting;
private String unitDesc = "";
private boolean isMain;
private int size;
private LayoutInflater inflater;
private int thumbSize = 200;
private File pic;
private TPictureCatalog pictureCatalog;
private TProductCatalog productCatalog;
//private ViewGroup hostActivity;
//int idTemp;
private LayoutInflater cursorInflater;
public ShygunInventoryGridCursorAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
this.mContext = context;
cursorInflater = (LayoutInflater) context.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
//this.cursor = c;
productCatalog=TProductCatalog.getInstance();
cyberSetting=CyberSetting.getInstance();
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = cursorInflater.inflate( R.layout.listview_inventory_product_griditems, parent, false);
ViewHolder holder = new ViewHolder();
holder.tvAttachment = (ImageView) view.findViewById(R.id.iv_inventory_products_griditems_attachment);
holder.imageCount = (TextView) view.findViewById(R.id.imagecount);
holder.tvItemCode = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_ItemCode);
holder.tvProductName = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_Title);
holder.tvPrice = (RialTextView) view.findViewById(R.id.tv_inventory_products_griditems_Price);
holder.tvRemain = (TextView) view.findViewById( R.id.tv_inventory_products_griditems_Remain);
holder.btnMore =(com.rey.material.widget.Button) view.findViewById(R.id.btn_inventory_products_griditems_More);
holder.btnPlus = (com.rey.material.widget.Button) view.findViewById(R.id.btn_inventory_products_griditems_addOne);
view.setTag(holder);
Log.d("CurAd","newView");
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
Log.d("CurAd","bindView");
ViewHolder holder;
holder = (ViewHolder) view.getTag();
holder.itemId = cursor.getString(cursor.getColumnIndex(DatabaseColumnContent.COL_PRODUCT_ITEM_ID.toString()));
TSimpleProduct tempProduct = productCatalog.getSimpleProductById(Integer.parseInt(holder.itemId));
holder.itemGuId = cursor.getString(cursor.getColumnIndex(DatabaseColumnContent.COL_PRODUCT_GUID.toString()));
holder.tvItemCode.setText(cursor.getString(cursor.getColumnIndex(DatabaseColumnContent.COL_PRODUCT_ITEMCODE.toString())));
holder.tvProductName.setText(cursor.getString(cursor.getColumnIndex(DatabaseColumnContent.COL_PRODUCT_ITEMDESC.toString())));
//Remain
if (cyberSetting.getSettingValue(TCyberSettingKey.SHOWITEMREMAIN).equals("1")) {
textTemp = (mContext.getString(R.string.restrictedInfo));
} else {
if (tempProduct.getDefaultUnitValue() == 2 && tempProduct.isUnitDependent()) {
String titleRemain2 = DatabaseColumnContent.COL_PRODUCT_CURSOR_REMAIN2.toString();
textTemp = cursor.getString(cursor.getColumnIndex(titleRemain2));
}
if (cyberSetting.getSettingValue(TCyberSettingKey.SHOWITEMREMAIN).equals("2")) {
if (textTemp == null) {
textTemp = "0";
}
int t = Integer.parseInt(textTemp);
if (t > 0) {
textTemp = mContext.getString(R.string.productAvailable);
} else {
textTemp = mContext.getString(R.string.productUnAvailable);
}
}
}
holder.tvRemain.setText(textTemp);
//Price
String priceLevel = "0";
try {
Register register = Register.getInstance();
priceLevel = register.getPriceLevel();
} catch (NoDaoSetException e) {
e.printStackTrace();
}
if(!priceLevel.equals("0"))
textTemp = cursor.getString(cursor.getColumnIndex(priceLevel));
else
textTemp = "0.0";
if (tempProduct.getDefaultUnitValue() == 2 && tempProduct.isUnitDependent()) {
double price2;
price2 = TLineItem.convertPrice1ToPrice2(Double.parseDouble(textTemp), tempProduct.isUnit1Bigger(), tempProduct.getUnitCoef());
textTemp = TGeneralTools.ConvertDoubleToEnglishString(price2);
if (tempProduct.getUnitDesc2() != null && !tempProduct.getUnitDesc2().equals(""))
unitDesc = " (" + tempProduct.getCompleteUnitDesc2() + ")";
} else {
if (tempProduct.getUnitDesc1() != null && !tempProduct.getUnitDesc1().equals(""))
unitDesc = " (" + tempProduct.getCompleteUnitDesc1() + ")";
}
holder.priceDef = textTemp;
holder.tvPrice.setText(textTemp + unitDesc);
holder.tvRemain.setText(holder.tvRemain.getText() + unitDesc);
//image
pictureCatalog = TPictureCatalog.getInstance();
String defGuid = "";
if (tempProduct.getHasAttachContent() >= 1 && pictureCatalog.isDownloadedAlbumAvailable()) {
defGuid = pictureCatalog.getDefaultPictureGuid(holder.itemGuId);
if (tempProduct.getHasAttachContent() == 1) {
holder.imageCount.setVisibility(View.GONE);
} else {
holder.imageCount.setVisibility(View.VISIBLE);
holder.imageCount.setText(String.valueOf(tempProduct.getHasAttachContent()));
}
} else {
holder.imageCount.setVisibility(View.GONE);
}
String filename = Environment.getExternalStorageDirectory().getPath()
+ FileAddressContent.APPLICATION_HOME_DIRECTORY
+ FileAddressContent.PICTURES_ROOT_DIRECTORY
//+ FileAddressContent.PICTURES_THUMBS_DIRECTORY.toString()
+ defGuid + FileAddressContent.PICTURES_EXTENSION;
pic = new File(filename);
if (pic.exists())
Picasso.with(mContext)
.load(pic)
.error(R.drawable.noimage)
//.placeholder(R.drawable.loading)
.resize(thumbSize, thumbSize)
.centerInside()
.into(holder.tvAttachment);
else
Picasso.with(mContext)
.load(R.drawable.noimage)
.resize(thumbSize, thumbSize)
.centerInside()
.into(holder.tvAttachment);
holder.tvAttachment.setMinimumHeight(thumbSize);
setupGridView(view, holder);
}
private void setupGridView(View view, final ViewHolder holder) {
/*final ImageView iv = (ImageView) view.findViewById(R.id.iv_inventory_products_griditems_attachment);
com.rey.material.widget.Button btMore = (com.rey.material.widget.Button) view.findViewById(R.id.btn_inventory_products_griditems_More);
com.rey.material.widget.Button btPlus = (com.rey.material.widget.Button) view.findViewById(R.id.btn_inventory_products_griditems_addOne);
//final TextView tvTitle = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_Title);
final RialTextView tvPrice = (RialTextView) view.findViewById(R.id.tv_inventory_products_griditems_Price);
final TextView tvItemId = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_ItemId);
final TextView tvGuId = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_GuId);
//final TextView tvRemain = (TextView) view.findViewById(R.id.tv_inventory_products_griditems_Remain);*/
holder.tvAttachment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* BitmapDrawable bitmapDrawable = ((BitmapDrawable) iv.getDrawable());*/
showImageDialog(holder.itemGuId);
}
});
holder.btnMore.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/*addToInvoiceDialog(tvTitle.getText().toString(), tvPrice.getText().toString(), tvItemId.getText().toString(),
tvRemain.getText().toString(),iv.getDrawable(),tvGuId.getText().toString());*/
showAddToInvoiceFragment(holder.itemId, holder.priceDef);
}
});
holder.btnPlus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//InventoryFragment.AddToInvoice(holder.itemId, 1, holder.priceDef, null, null);
}
});
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
private void showImageDialog(String ReferenceGuId) {
//InventoryFragment.openAlbum(ReferenceGuId);
}
private void showAddToInvoiceFragment(String itemId, String priceDef) {
//InventoryFragment.showAddToInvoiceFragment(itemId, priceDef);
}
}
这是我设置适配器的java代码中的一部分:
ShygunInventoryGridCursorAdapter listAdapter1 = new ShygunInventoryGridCursorAdapter(context,cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
gridView.setNumColumns(colCount);
gridView.setAdapter(listAdapter1);
MAT屏幕(我无法到达任何地方,我的意思是非根或......是我自己的代码)
更不用说,在适配器的System.gc()
方法末尾添加get View
将解决所有问题,但我确定它不是正确的做法