我仍然是开发Android应用程序的初学者,我想制作一个填充了海关项目的列表视图(每个都包含一个imageview和一个textview)。这部分工作完美但是...
我添加了一个按钮,可以让我用默认相机拍照并将其保存在外部存储器中。当我拍摄照片时,我还会创建一个带有照片名称和Uri的新对象。
然后你可能已经理解了,我在ListView中加载了我的对象列表。但是只有在6或7张照片后我才能得到#34;内存异常"。
我的智能手机拍摄高分辨率照片,我猜这张照片已完全装入内存,导致异常。我从developper android:https://developer.android.com/training/displaying-bitmaps/load-bitmap.html尝试了很多这样的教程。但它并没有改变任何事情。我显然做错了什么。
如果有人能帮助我,我将非常感激:D
PS:我的列表视图是片段,我不知道它是否重要。 此外,当我用后置摄像头拍摄照片时,照片不会显示在列表中:/只显示一个空白。但是当我用前置摄像头拍摄时,这是正确显示的。
我的代码: MainFragment.java
public class MainFragment extends Fragment{
private ListView frais_listView;
private Uri saved_image_uri;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView=inflater.inflate(R.layout.fragment_main,container,false);
return rootView;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.new_frais_button);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent newfraisactivity = new Intent(getActivity(),NewFraisActivity.class);
startActivity(newfraisactivity);
}
});
FloatingActionButton fab2 = (FloatingActionButton) view.findViewById(R.id.new_frais_photo_button);
fab2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Get the current date
Calendar calendar=Calendar.getInstance();
SimpleDateFormat date_format=new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss");
String formatted_date=date_format.format(calendar.getTime());
//Open the default camera and save the photo
Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
saved_image_uri=Uri.fromFile(new File(Utilities.getImages_folder()+"/Frais"+formatted_date+".png"));
camera.putExtra(MediaStore.EXTRA_OUTPUT,saved_image_uri);
startActivityForResult(camera,0);
}
});
//Load the list of frais in the listview using a custom adapter FraisAdapter
frais_listView=(ListView)getActivity().findViewById(R.id.frais_listview);
FraisAdapter my_adapter=new FraisAdapter(getActivity().getBaseContext(),R.layout.frais_item_for_listview,Frais.frais_list);
frais_listView.setAdapter(my_adapter);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
//If the photo has been taken, create a new Frais object and add it to the list
if(resultCode != 0)
{
String filename=(new File(saved_image_uri.toString())).getName();
int position = filename.lastIndexOf(".");
String filename_noext = position > 0 ? filename.substring(0, position) : filename;
Frais.frais_list.add(new Frais(filename_noext,null,saved_image_uri));
}
}
}
FraisAdapter.java
public class FraisAdapter extends ArrayAdapter<Frais> {
Context context;
int layoutResourceId;
LayoutInflater inflater;
ArrayList<Frais> data= null;
public FraisAdapter(Context context, int layoutResourceId, ArrayList<Frais> data) {
super(context, layoutResourceId, data);
this.context=context;
this.layoutResourceId=layoutResourceId;
this.data = data;
inflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = convertView;
FraisHolder holder;
if (row == null)
{
row = inflater.inflate(layoutResourceId, null);
holder = new FraisHolder();
holder.title = (TextView) row.findViewById(R.id.frais_item_title);
holder.image = (ImageView) row.findViewById(R.id.frais_item_imageview);
row.setTag(holder);
}
else
{
holder = (FraisHolder) row.getTag();
}
Frais frais = data.get(position);
//holder.image.setImageURI(frais.getImage());
holder.image.setImageBitmap(Utilities.decodeSampledBitmap(frais.getImage().getPath(),16,16));
holder.title.setText(frais.getNom());
return row;
}
static class FraisHolder {
public TextView title;
public ImageView image;
}
}
Utilities.java
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;
}
public static Bitmap decodeSampledBitmap(String path, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path);
}
最后我的错误:
java.lang.OutOfMemoryError: Failed to allocate a 51916812 byte allocation with 10359328 free bytes and 9MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStreamInternal(BitmapFactory.java:635)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:611)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:391)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:417)
at ip1a.metier.Utilities.decodeSampledBitmap(Utilities.java:58)
at ip1a.adapters.FraisAdapter.getView(FraisAdapter.java:59)
at android.widget.AbsListView.obtainView(AbsListView.java:2346)
at android.widget.ListView.makeAndAddView(ListView.java:1876)
at android.widget.ListView.fillDown(ListView.java:702)
at android.widget.ListView.fillSpecific(ListView.java:1367)
at android.widget.ListView.layoutChildren(ListView.java:1696)
at android.widget.AbsListView.onLayout(AbsListView.java:2148)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1192)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v4.widget.DrawerLayout.onLayout(DrawerLayout.java:1187)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWindow$DecorView.onLayout(PhoneWindow.java:2934)
at android.view.View.layout(View.java:16639)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2171)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1931)
at androi
答案 0 :(得分:0)
尝试像这样添加
options.inPurgeable=true; //It will clear the cache when it overflows
在decodeSampledBitmap()
函数
或者第二种方法是使用
调整位图大小 Bitmap.createScaledBitmap()