2012-10-24 16 views
6

Sto utilizzando una finestra di dialogo per visualizzare le immagini nel mio progetto Android. Il primo si apre bene, ma quando lo chiudo e faccio di nuovo il processo per mostrarne uno diverso, l'app cade con un errore di memoria (è in esecuzione su un Samsung Galaxy s3 - quindi non dovrebbe essere un problema).Visualizzazione delle foto esaurita memoria

Errore:

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) 

codice Caricamento:

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: Quello che sto usando per renderlo ora lavoro:

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

Cosa spettacoli profiler di memoria? Qual è la dimensione dell'heap, memoria heap-free? – sandrstar

+0

Heap ha sparato fino a 44mb quando ho caricato la foto. C'è un altro modo per farlo? 1 \t 45,258 MB \t 44,830 MB \t 438,242 KB \t 99,05% \t 57,128 – TMB87

+0

Come sai che l'altezza e la larghezza sono 500? –

risposta

5

Ho sperimentato questo e non so se la mia risposta è delle migliori pratiche o no però ...

Questo è probabilmente il problema:

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

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

se si carica un'immagine di grandi dimensioni, allora probabilmente stai per esaurire la memoria. Inoltre si esaurirà la memoria se non si utilizza una gestione della memoria decente quando si carica una serie di immagini.

Ho utilizzato il BitmapFactory per decodificare il file e ho utilizzato lo BitmapFactory.Options per creare un nuovo Bitmap scializzato che ho quindi visualizzato sullo schermo.

L'idea è che BitmapFactory.Options offre un maggiore controllo sulla memoria potenziale che l'immagine potrebbe utilizzare. Ad esempio non è necessario mostrare un'immagine a 1920x1080 a schermo intero su uno schermo che non supporta nemmeno quelle risoluzioni.

Esistono alcune domande di stackoverflow correlate che potrebbero essere di aiuto e in particolare: Handling large Bitmaps, che si concentra sull'opzione BitmapFactory.Options inJustDecodeBounds.

Infine, ho trovato questa fantastica libreria leggera denominata Aquery. Ha un sacco di metodi per gestire file di grandi dimensioni, e finora lo fa bene. Vale la pena dare un'occhiata. Usa un paradigma simile a Jquery per quanto riguarda lo sviluppo web (da cui il nome) e introduce una sintassi più breve per manipolare Views. La sezione seguente delle loro offerte di documentazione con il caricamento delle immagini sia in locale che da una fonte remota, incluse le immagini ripiegare:

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

+0

Grazie per questo, ho appena guardato la fabbrica bitmap e ora ho sto comprimendo mentre vado – TMB87

Problemi correlati