我在android中使用sqlite,现在我需要用50多个图像和描述填充一个数据库,我在数据库中保存图像名称,然后将图像保存在资源上。问题出在列表视图上,我在其中使用了以下代码的图像。
int resId = getResources().getIdentifier(poiAtual.get_imagemURI(),"drawable",getPackageName());
holder.foto.setImageResource(resId);
当我快速上下滚动时,应用程序将崩溃并显示内存不足错误。有更有效的方法吗??
感谢
编辑:这是我的getview
private class POIListAdapter extends ArrayAdapter<POI> {
public POIListAdapter() {
super (Lista.this, R.layout.item_listview, POIs);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
// lstPOIs.setScrollingCacheEnabled(false);//TODO PARA TESTAR FORMA DE A LISTA NAO TER LAG, usar viewholder
ViewHolder holder;
if (view == null) {
view = getLayoutInflater().inflate(R.layout.item_listview, parent, false);
holder = new ViewHolder();
holder.id= (TextView) view.findViewById(R.id.txtID);
holder.nome = (TextView) view.findViewById(R.id.txtNomePOI);
holder.descricao = (TextView) view.findViewById(R.id.txtDescricao);
holder.foto = (ImageView) view.findViewById(R.id.ivFoto);
view.setTag(holder);
}
else {
holder = (ViewHolder) view.getTag();
}
POI poiAtual = POIs.get(position);
//TextView id=(TextView)view.findViewById(R.id.txtID);
holder.id.setText(Integer.toString(poiAtual.get_id()));
//TextView name = (TextView) view.findViewById(R.id.txtNomePOI);
holder.nome.setText(poiAtual.get_nomePOI());
//TextView phone = (TextView) view.findViewById(R.id.txtTema);
// phone.setText(poiAtual.get_tema());
//TextView descricao = (TextView) view.findViewById(R.id.txtDescricao);
holder.descricao.setText(poiAtual.get_descricao());
// ImageView ivFoto = (ImageView) view.findViewById(R.id.ivFoto);
//ivContactImage.setImageURI(poiAtual.get_imagemURI());
int resId = getResources().getIdentifier(poiAtual.get_imagemURI(),"drawable",getPackageName());
holder.foto.setImageResource(resId);
return view;
}
}
Lazy加载您的图像,根据使用情况适当调整它们的大小,并将它们存储在本地缓存中,这样您只会在第一次需要调整大小时进行调整。
加载位图时,您应该从这里开始了解最佳实践。如果要将非常大的位图加载到图像视图中,则应将位图缩放到图像视图的边界,这样就不会浪费不必要的内存。类似这样的东西:
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
或者你可以使用像Picasso这样的图像库,它可以为你处理大部分开销,比如内存缓存、缩放等。
您还应该注意硬引用,它可能会防止图像视图被破坏,从而导致内存泄漏。
您几乎应该永远不要使用android:largeHeap="true"
。通常,这被用作糟糕编程的支撑。以下是安卓开发者页面的一个片段:
但是,请求大型堆的功能仅适用于可以证明需要消耗更多RAM的小应用程序集(例如作为大型照片编辑应用程序)。永远不要简单地请求一个大堆因为你的内存用完了,你需要快速修复——你应该只有当你确切地知道你所有的记忆在哪里时才使用它以及为什么必须保留。然而,即使你很自信你的应用程序可以证明大堆是合理的,你应该避免请求它无论在何种程度上可能。使用额外的内存将越来越多由于垃圾当任务切换或执行其他常见操作。