由位图的列表视图引起的内存不足异常

时间:2016-05-21 13:31:06

标签: android listview bitmap

我仍然是开发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

1 个答案:

答案 0 :(得分:0)

尝试像这样添加

 options.inPurgeable=true; //It will clear the cache when it overflows

decodeSampledBitmap()函数

或者第二种方法是使用

调整位图大小
   Bitmap.createScaledBitmap()