我制作了一个Android应用程序,当网络不可用时,图像将保存到本地数据库。我将图像uri保存在数据库表中,并从图像uri中检索图像,并使用自定义数组适配器在imageView
的{{1}}上显示该图像。当我使用模拟器运行我的应用程序时,它运行良好。然而,当使用Android手机时,它显示强制关闭错误。
错误日志如下:
listView
我的自定义适配器如下:
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:504)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:370)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:715)
at android.graphics.drawable.Drawable.createFromStream(Drawable.java:675)
at android.widget.ImageView.resolveUri(ImageView.java:525)
at android.widget.ImageView.setImageURI(ImageView.java:309)
at com.freedom.net.Syncho2$NoteListAdapter.getView(Syncho2.java:219)
at android.widget.AbsListView.obtainView(AbsListView.java:1519)
at android.widget.ListView.makeAndAddView(ListView.java:1749)
at android.widget.ListView.fillDown(ListView.java:674)
at android.widget.ListView.fillFromTop(ListView.java:731)
at android.widget.ListView.layoutChildren(ListView.java:1602)
at android.widget.AbsListView.onLayout(AbsListView.java:1349)
at android.view.View.layout(View.java:7320)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1263)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1137)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1051)
at android.view.View.layout(View.java:7320)
at android.widget.FrameLayout.onLayout(FrameLayout.java:342)
at android.view.View.layout(View.java:7320)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1263)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1137)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1051)
at android.view.View.layout(View.java:7320)
at android.widget.FrameLayout.onLayout(FrameLayout.java:342)
at android.view.View.layout(View.java:7320)
at android.view.ViewRoot.performTraversals(ViewRoot.java:1162)
我从这样的活动中调用此适配器:
public class NoteListAdapter extends ArrayAdapter<ImageFromDB> {
Context c;
ArrayList<ImageFromDB> image = null;
ArrayList<String> uriImage = null;
ArrayList<Integer> ID = null;
private AllId allid = null;
DBAdapter db = null;
WatchListAllEntity watchListAllEntity=null;
int flagVariable=1;
private ArrayList<ImageFromDB> items;
public NoteListAdapter(Context context, int textViewResourceId,
ArrayList<ImageFromDB> items) {
super(context, textViewResourceId, items);
Log.e("sf","123");
this.items = items;
c=context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
final int myPosition = position;
if (v == null) {
LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listitempict2, null);
}
ImageFromDB re = items.get(position);
Log.e("re", re+"");
if (re != null) {
ImageView tt = (ImageView) v.findViewById(R.id.imageviewproduct);
String imageUri = re.getImageuri();
Log.e("imageUri", imageUri+"");
tt.setImageURI(Uri.parse(imageUri));
final CheckBox checkBox = (CheckBox) v.findViewById(R.id.checkboxproduct);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (isChecked) {
if(flagVariable==1)
{
String ImUri = items.get(myPosition).getImageuri();
allid.setImageUri(ImUri);
allid.setId(items.get(myPosition).getId());
flagVariable++;
Log.e("flagVariable : " , flagVariable+"");
}
else
{
checkBox.setChecked(false);
//Toast.makeText(Syncho2.this,"正しく選んでください。",Toast.LENGTH_SHORT).show();
}
} else {
flagVariable=1;
Log.e("flagVariable : " , flagVariable+"");
}
}
});
}
return v;
}
}
我从调试中注意到,当图像仅两次时,适配器被称为六次。 五次它返回视图,但在第六次时显示该错误。
答案 0 :(得分:2)
阅读本文:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html 并且您将能够毫无错误地加载图像!
答案 1 :(得分:0)
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
// if it's not recycled, initialize some attributes
if (row == null) {
LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
row = li.inflate(R.layout.menucategory, null);
//imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
}
// getCategoryItem
Category category = (Category) getItem(position);
// Get reference to ImageView
categoryIcon = (ImageView) row.findViewById(R.id.category_image);
//categoryIcon.setLayoutParams(new GridView.LayoutParams(85, 85));
categoryIcon.setScaleType(ImageView.ScaleType.CENTER_CROP);
categoryIcon.setPadding(5, 5, 5, 5);
categoryName = (TextView) row.findViewById(R.id.category_name);
//Set category name
categoryName.setText(category.getCategoryName());
if(category.getCategoryPath() != null){
Bitmap bitmap = BitmapFactory.decodeFile(category.getCategoryPath());
System.out.println("bitmap2:: "+ bitmap);
if(bitmap != null){
categoryIcon.setImageBitmap(bitmap);
}
}
return row;
}
答案 2 :(得分:0)
我找到了解决方案。我应该知道android应用程序的内存管理。 http://www.youtube.com/watch?v=_CruQY55HOk。当我试图直接在ImageView上显示图像Uri时,问题就是创建。我的每个人都应该避免使用像ImageView.setImageURI(Uri.parse(imageUri))这样的代码。而不是那样,尝试在imageview上加载位图或drawable。