2016-05-21 13 views
0

Ich bin noch ein Anfänger Android-Anwendungen in developping und ich möchte eine Listenansicht mit den Zollpositionen (jede enthält einen Imageview und Textview) gefüllt machen. Dieser Teil funktioniert perfekt, ABER ...Nicht genügend Arbeitsspeicher durch Listenansicht von Bitmap verursacht Ausnahme

Ich habe eine Schaltfläche, die ich ein Foto mit der Standard-Kamera nehmen kann und es auf dem externen Speicher zu speichern. Wenn ich das Foto mache, erstelle ich auch ein neues Objekt mit dem Namen des Fotos und des Uri.

Dann haben Sie vielleicht verstanden, ich lade meine Liste von Objekten in der ListView. Aber erst nach 6 oder 7 Fotos bekam ich diese "Out of Memory Exception".

Mein Smartphone nehmen hochauflösende Fotos und ich denke, dass das Foto vollständig im Speicher, die diese Ausnahme verursachen geladen wird. Ich habe viele Dinge wie dieses Tutorial von Entwickler Android: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html versucht. Aber es ändert nichts. Ich mache offensichtlich etwas falsch.

So würde ich sehr dankbar, wenn mir jemand helfen könnte: D

PS: Meine Listenansicht in einem Fragmente ist, ich weiß nicht, ob es wichtig ist. Außerdem, wenn ich das Foto mit der Rückkamera mache, wird das Foto nicht in der Liste angezeigt:/nur ein Leerzeichen erscheint. Aber wenn ich es mit der Frontkamera nehme, wird dies korrekt angezeigt.

Mein Code: 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); 

} 

Und schließlich mein Fehler:

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

, um der Größe Hast du nicht versucht, das Bitm zu verkleinern? aps, bevor Sie sie zu Ihrer Listview hinzufügen? –

Antwort

0

versuchen, wie diese

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

in decodeSampledBitmap() Funktion

Oder zweite Möglichkeit hinzuzufügen, ist die Bitmap mit

Bitmap.createScaledBitmap() 
Verwandte Themen