2012-10-24 6 views
6

Ich verwende ein Dialogfeld, um Bilder in meinem Android-Projekt anzuzeigen. Der erste öffnet sich gut, aber wenn ich ihn schließe und den Prozess erneut mache, um einen anderen zu zeigen, fällt die App mit einem Speicherfehler aus (es läuft auf einer Samsung Galaxie S3 - sollte also kein Problem sein).Das Anzeigen von Fotos hat keinen Speicherplatz mehr

Fehler:

10-24 11:25:45.575: E/dalvikvm-heap(29194): Out of memory on a 31961104-byte allocation. 
10-24 11:25:45.580: E/AndroidRuntime(29194): FATAL EXCEPTION: main 
10-24 11:25:45.580: E/AndroidRuntime(29194): java.lang.OutOfMemoryError 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:389) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:418) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.graphics.drawable.Drawable.createFromPath(Drawable.java:882) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.ImageView.resolveUri(ImageView.java:569) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.ImageView.setImageURI(ImageView.java:340) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.directenquiries.assessment.tool.AddAsset.loadPhoto(AddAsset.java:771) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.directenquiries.assessment.tool.AddAsset$11.onClick(AddAsset.java:748) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:936) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AdapterView.performItemClick(AdapterView.java:292) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView.performItemClick(AbsListView.java:1359) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView$PerformClick.run(AbsListView.java:2988) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.widget.AbsListView$1.run(AbsListView.java:3783) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Handler.handleCallback(Handler.java:605) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Handler.dispatchMessage(Handler.java:92) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.os.Looper.loop(Looper.java:137) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at android.app.ActivityThread.main(ActivityThread.java:4517) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at java.lang.reflect.Method.invokeNative(Native Method) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at java.lang.reflect.Method.invoke(Method.java:511) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760) 
10-24 11:25:45.580: E/AndroidRuntime(29194): at dalvik.system.NativeStart.main(Native Method) 

Laden Code:

public void loadPhotoList(){ 

    Cursor f = db.rawQuery("select * from stationphotos where StationObjectID = '"+ checkStationObjectID + "'", null); 
    final ArrayList<String> mHelperNames= new ArrayList<String>(); 

      if(f.getCount() != 0) { 
       f.moveToFirst(); 

       f.moveToFirst(); 
       while(!f.isAfterLast()) { 
        mHelperNames.add(f.getString(f.getColumnIndex("FilePath"))); 
        f.moveToNext(); 
       } 
      } 
    f.close(); 
    final String [] nameStrings = new String [mHelperNames.size()]; 

    for(int i=0; i<mHelperNames.size(); i++) 
     nameStrings[i] = mHelperNames.get(i).toString(); 


    AlertDialog.Builder builder = new AlertDialog.Builder(this); 

    builder.setTitle("Select Picture"); 
    builder.setItems(nameStrings, new DialogInterface.OnClickListener() { 

     public void onClick(DialogInterface dialog, int item) { 

      loadPhoto(mHelperNames.get(item).toString()); 

     } 

    }); 

    AlertDialog alert = builder.create(); 

    alert.show(); 

} 


public void loadPhoto(String imagepath){ 

    Dialog dialog = new Dialog(this); 
    dialog.setContentView(R.layout.activity_show_image); 
    dialog.setTitle("Image"); 
    dialog.setCancelable(true); 

    ImageView img = (ImageView) dialog.findViewById(R.id.imageView1); 
    img.setImageResource(R.drawable.ico_partial); 
    Uri imgUri = Uri.parse(imagepath); 
    img.setImageURI(imgUri); 


    dialog.show(); 
} 

Edit: Was ich verwende es jetzt funktioniert:

public static Bitmap decodeSampledBitmapFromFile(String imagePath, int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(imagePath, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeFile(imagePath, options); 
} 
    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) { 
     if (width > height) { 
      inSampleSize = Math.round((float)height/(float)reqHeight); 
     } else { 
      inSampleSize = Math.round((float)width/(float)reqWidth); 
     } 
    } 
    return inSampleSize; 
} 



img.setImageBitmap(decodeSampledBitmapFromFile(imagepath, 500, 500)); 
+0

Was Speicher-Profiler zeigt das? Was ist Heap-Größe, Heap-Speicher? – sandrstar

+0

Heap geschossen bis zu 44 MB, als ich das Foto geladen habe. Gibt es einen anderen Weg, es zu tun? 1 \t 45.258 MB \t 44,830 MB \t 438,242 KB \t 99,05% \t 57,128 – TMB87

+0

Wie Sie wissen, die Höhe und Breite ist 500? –

Antwort

5

Ich habe diese Erfahrung gemacht und ich weiß nicht, ob meine Antwort beste Praxis oder nicht jedoch ...

Dies ist wahrscheinlich Ihr Problem ist:

Uri imgUri = Uri.parse(imagepath); 
    img.setImageURI(imgUri); 

Heap shot up to 44mb when I loaded the photo.

Wenn Sie ein großes Bild laden dann Sie werden wahrscheinlich nicht mehr genügend Speicher haben. Wenn Sie beim Laden einer Reihe von Bildern keine vernünftige Speicherverwaltung verwenden, ist auch nicht genügend Speicher verfügbar.

Ich habe die BitmapFactory verwendet, um die Datei zu dekodieren und die verwendet, um eine neue sclaed Bitmap zu erstellen, die ich dann auf dem Bildschirm angezeigt wurde.

Die Idee ist, dass die BitmapFactory.Options Ihnen mehr Kontrolle über den potenziellen Speicher gibt, den Ihr Bild verbrauchen könnte. Zum Beispiel ist es nicht notwendig, ein 1920x1080 Bild in voller Größe auf einem Bildschirm zu zeigen, der diese Auflösungen nicht unterstützt.

Es gibt einige verwandte Stackoverflow-Fragen, die Ihnen und insbesondere helfen könnten: Handling large Bitmaps, die sich auf die BitmapFactory.Options-Option inJustDecodeBounds konzentriert.

Endlich habe ich diese großartige leichte Bibliothek namens Aquery gefunden. Es hat eine ganze Reihe von Methoden, um große Dateien zu verarbeiten, und bisher ist es gut gelungen. Einen Blick wert. Es verwendet ein ähnliches Paradigma zu Jquery in Bezug auf Web-Entwicklung (daher der Name) und führt eine kürzere Syntax für die Manipulation von Ansichten ein. Der folgende Abschnitt ihrer Dokumentation befasst sich mit Bild Laden sowohl lokal als auch von einer entfernten Quelle, einschließlich zurückgreifen Bilder:

http://code.google.com/p/android-query/wiki/ImageLoading

+0

Vielen Dank für diese, ich sah nur in der Bitmap-Fabrik und jetzt i Ich komprimiere, wie ich gehe – TMB87

Verwandte Themen