2011-11-23 16 views
5

Publiqué una pregunta anoche sobre este tema, pero no creo que lo haya explicado lo suficiente como para obtener la ayuda adecuada. Entonces, básicamente, tengo una aplicación donde puedes presionar un botón que te permitirá seleccionar una imagen de tu galería y mostrarla en un ImageView que he mostrado en la aplicación. Todo esto funciona genial Sin embargo, cuando presiono el botón nuevamente y elijo una imagen diferente, la fuerza de la aplicación se cierra.asignación externa demasiado grande para este proceso

ACTUALIZACIÓN Ahora, si tomo una foto de la carpeta de fotos de mi descarga en la galería, funciona bien, puedo cambiar las fotos con la frecuencia que desee. Pero cuando vuelvo a la carpeta de fotos de mi cámara para cambiar la imagen, se cierra forzadamente.

ACTUALIZACIÓN 2 También funciona bien con cualquier otra carpeta que tengo en mi aplicación de Galería. Solo uno que tiene este problema (forzar cierre) está en la carpeta "Cámara"

ACTUALIZACIÓN 3 19660800-byte asignación externa demasiado grande para este proceso. está causando el problema ¿Alguna forma de reducir el tamaño de las fotos seleccionadas?

 private static final int SELECT_PICTURE = 1; 

     private String selectedImagePath; 
     private ImageView img; 

     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.main); 

      img = (ImageView)findViewById(R.id.myimageview); 

      ((Button) findViewById(R.id.taptoadd)) 
        .setOnClickListener(new OnClickListener() { 
         public void onClick(View arg0) { 
          Intent intent = new Intent(); 
          intent.setType("image/*"); 
          intent.setAction(Intent.ACTION_GET_CONTENT); 
          startActivityForResult(Intent.createChooser(intent,"Select Picture"), SELECT_PICTURE); 
         } 
        }); 
     } 

     public void onActivityResult(int requestCode, int resultCode, Intent data) { 
      if (resultCode == RESULT_OK) { 
       if (requestCode == SELECT_PICTURE) { 
        Uri selectedImageUri = data.getData(); 
        selectedImagePath = getPath(selectedImageUri); 
        System.out.println("Image Path : " + selectedImagePath); 
        img.setImageURI(selectedImageUri); 
       } 
     } 
     } 

     public String getPath(Uri uri) { 
     String[] projection = { MediaStore.Images.Media.DATA }; 

      Cursor cursor = managedQuery(uri, projection, null, null, null); 
      int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); 
      cursor.moveToFirst(); 
      return cursor.getString(column_index); 


     } 

aquí es el registro de

   11-23 16:33:15.871: D/dalvikvm(9171): GC_EXTERNAL_ALLOC freed 51K, 49% free 2793K/5447K, external 20868K/22916K, paused 50ms 
    11-23 16:33:15.878: E/dalvikvm-heap(9171): 19660800-byte external allocation too large for this process. 
    11-23 16:33:15.886: E/GraphicsJNI(9171): VM won't let us allocate 19660800 bytes 
    11-23 16:33:15.906: D/dalvikvm(9171): GC_FOR_MALLOC freed <1K, 49% free 2792K/5447K, external 1668K/20868K, paused 18ms 
    11-23 16:33:15.906: D/skia(9171): --- decoder->decode returned false 
    11-23 16:33:15.906: D/AndroidRuntime(9171): Shutting down VM 
    11-23 16:33:15.910: W/dalvikvm(9171): threadid=1: thread exiting with uncaught exception (group=0x40015560) 
    11-23 16:33:15.937: E/AndroidRuntime(9171): FATAL EXCEPTION: main 
    11-23 16:33:15.937: E/AndroidRuntime(9171): java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:470) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:336) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:697) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.graphics.drawable.Drawable.createFromStream(Drawable.java:657) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.widget.ImageView.resolveUri(ImageView.java:521) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.widget.ImageView.setImageURI(ImageView.java:305) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at snapshot.app.LinearLayoutsActivity.onActivityResult(LinearLayoutsActivity.java:48) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.Activity.dispatchActivityResult(Activity.java:3908) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.ActivityThread.deliverResults(ActivityThread.java:2528) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.ActivityThread.handleSendResult(ActivityThread.java:2574) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.ActivityThread.access$2000(ActivityThread.java:117) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.os.Handler.dispatchMessage(Handler.java:99) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.os.Looper.loop(Looper.java:130) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at android.app.ActivityThread.main(ActivityThread.java:3683) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at java.lang.reflect.Method.invokeNative(Native Method) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at java.lang.reflect.Method.invoke(Method.java:507) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 
    11-23 16:33:15.937: E/AndroidRuntime(9171):  at dalvik.system.NativeStart.main(Native Method) 
+1

puede publicar la salida de Logcat cuando se cierra la fuerza de la aplicación? – slayton

+0

Agregué el registro. La aplicación solo se cierra cuando se cambian las fotos de la carpeta "Cámara", todas las otras carpetas funcionan bien. – dabious

+0

Parece que las fotos en la carpeta de la cámara son demasiado grandes y causan un error OOM. Android solo tiene 16 MB de almacenamiento dinámico para una aplicación. – blessenm

Respuesta

5

El error que está medios que el mapa de bits que va a cargar es demasiado grande recibiendo. Necesitas disminuir la resolución. Ver esta cuestión para algunos grandes ejemplos de cómo hacer frente a este: Strange out of memory issue while loading an image to a Bitmap object

actualización: En lugar de decir la ImageView cuales URI para cargar como un mapa de bits, es necesario cargar el mapa de bits primero a sí mismo y luego configurar ese mapa de bits como la imagen en ImageView. Esto es bastante sencillo.

Para cargar un mapa de bits de usted primero debe convertir el URI en una cadena (creo que se puede utilizar URI.getPath() aunque no estoy seguro) que contiene la ruta de la imagen, puede cargar el mapa de bits con:

Bitmap b = BitmapFactory.decodeFile(pathToImage); 

Esto decodificará todo el mapa de bits, en su lugar, desea reducir la resolución del mapa de bits a la resolución deseada. Digamos que su vista de la imagen será de 125x125 píxeles y su imagen de 1000x1000 píxeles. 125/1000 = 8 por lo que solo tenemos que decodificar cada 8vo píxel. Para hacer esto, hacemos lo siguiente:

int inSample = 8; 

opts = new BitmapFactory.Options(); 
opts.inSampleSize = inSample; 

Bitmap b = BitmapFactory.decodeFile(pathToImage, opts); // this bitmap will be 1/8 the size of the original 

Es bastante directo y debería resolver sus problemas de memoria. Vea la segunda parte de mi respuesta a esta pregunta: Android GalleryView Recycling para una explicación más extensa.

+0

No puedo, por mi vida, conseguir algo de eso funcionando. :/(Admisión - Soy MUY nuevo en todo esto, obviamente.) – dabious

+0

@dabious ver mi actualización – slayton

+0

¡Impresionante! Gracias. – dabious

Cuestiones relacionadas