studio outofmemoryerror libreria glide ejemplo bitmaps android bitmap out-of-memory image-capture

outofmemoryerror - scale bitmap android



java.lang.OutOfMemoryError-BitmapFactory.decode(strPath) (5)

Obtengo java.lang.OutOfMemoryError , cuando llamo UploadActivity.java

El número de línea 176 es:

Bitmap bm = BitmapFactory.decodeFile(strPath);

Ver mi registro:

12-07 17:57:10.585: E/AndroidRuntime(16708): FATAL EXCEPTION: main 12-07 17:57:10.585: E/AndroidRuntime(16708): java.lang.OutOfMemoryError 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:650) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:389) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:449) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.example.camera.UploadActivity$ImageAdapter.getView(UploadActivity.java:176) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.AbsListView.obtainView(AbsListView.java:2465) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.makeAndAddView(ListView.java:1775) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.fillDown(ListView.java:678) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.fillFromTop(ListView.java:739) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.ListView.layoutChildren(ListView.java:1628) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.AbsListView.onLayout(AbsListView.java:2300) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.RelativeLayout.onLayout(RelativeLayout.java:948) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1655) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1513) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.LinearLayout.onLayout(LinearLayout.java:1426) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.widget.FrameLayout.onLayout(FrameLayout.java:448) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.View.layout(View.java:14063) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewGroup.layout(ViewGroup.java:4607) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1996) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1817) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1114) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4520) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer.doCallbacks(Choreographer.java:555) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer.doFrame(Choreographer.java:525) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Handler.handleCallback(Handler.java:615) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Handler.dispatchMessage(Handler.java:92) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.os.Looper.loop(Looper.java:137) 12-07 17:57:10.585: E/AndroidRuntime(16708): at android.app.ActivityThread.main(ActivityThread.java:4921) 12-07 17:57:10.585: E/AndroidRuntime(16708): at java.lang.reflect.Method.invokeNative(Native Method) 12-07 17:57:10.585: E/AndroidRuntime(16708): at java.lang.reflect.Method.invoke(Method.java:511) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036) 12-07 17:57:10.585: E/AndroidRuntime(16708): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803) 12-07 17:57:10.585: E/AndroidRuntime(16708): at dalvik.system.NativeStart.main(Native Method)

UploadActivity.java:-

public class ImageAdapter extends BaseAdapter { private Context context; public ImageAdapter(Context c) { // TODO Auto-generated method stub context = c; } public int getCount() { // TODO Auto-generated method stub return ImageList.size(); } public Object getItem(int position) { // TODO Auto-generated method stub return position; } public long getItemId(int position) { // TODO Auto-generated method stub return position; } public View getView(final int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub LayoutInflater inflater = (LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (convertView == null) { convertView = inflater.inflate(R.layout.list_upload, null); } // ColImgName TextView txtName = (TextView) convertView.findViewById(R.id.ColImgName); strPath = ImageList.get(position).toString(); // Get File Name fileName = strPath.substring( strPath.lastIndexOf(''/'')+1, strPath.length() ); File file = new File(strPath); @SuppressWarnings("unused") long length = file.length(); txtName.setText(fileName); // Image Resource ImageView imageView = (ImageView) convertView.findViewById(R.id.ColImgPath); Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm); // ColStatus final ImageView txtStatus = (ImageView) convertView.findViewById(R.id.ColStatus); txtStatus.setImageResource(R.drawable.bullet_button); // progressBar final ProgressBar progress = (ProgressBar) convertView.findViewById(R.id.progressBar); progress.setVisibility(View.GONE); //btnUpload final ImageButton btnUpload = (ImageButton) convertView.findViewById(R.id.btnUpload); btnUpload.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { // Upload btnUpload.setEnabled(false); startUpload(position); } }); return convertView; } }


antes de llamar a Bitmap bm = BitmapFactory.decodeFile (strPath);

llame a esto .. Bitmap bm = decodeSampledBitmapFromResource (strPath, reqWidth, reqHeight);

si vuelves a obtener java.lang.OutOfMemoryError, avísame

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 decodeSampledBitmapFromResource(String strPath,int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(strPath, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options,reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(strPath, options);; }


Es un problema de optimización para su aplicación. Está obteniendo OutOfMemoryError porque cuando está haciendo BitmapFactory.decodeFile (strPath), Android está intentando asignar memoria para ese mapa de bits. En su caso, el sistema no puede encontrar suficiente espacio libre para asignar y es por eso que está recibiendo este error.

Ahora, como puedo ver en su código, está intentando mostrar una lista de imágenes usando ImageAdapter. En ese caso, su vista de imagen debe tener un ancho y una altura más pequeños que la imagen real.

Para darte una idea más general, esto es lo que está sucediendo:

  • Ancho de ImageView * altura = 100dp * 100dp
  • Ancho de la imagen * altura = 800px * 800px.

En este escenario, aunque nuestra vista de imagen ancho-alto es 100 * 100, estamos intentando establecer una imagen de 800 * 800 como fondo. Y esta definitivamente no es una forma eficiente porque el sistema asignará memoria para una imagen de 800 * 800px mientras que 100 * 100 lo haría.

Por eso, antes de realizar cualquier decodificación del mapa de bits, debe muestrear el mapa de bits de modo que solo se asigne 100 * 100 de memoria.

Encontrará una versión más detallada de esta explicación developer.android.com/training/displaying-bitmaps/…


Necesitas reciclar el objeto Bitmap.

Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm);

Después de las líneas de código anteriores en su vista de obtención, simplemente agregue el código escrito abajo /// ahora recicle su mapa de bits, esto liberará su memoria en cada iteración

if(bm!=null) { bm.recycle(); bm=null; }

Después de esto también si está obteniendo el mismo error el

Reemplace el código de abajo

Bitmap bm = BitmapFactory.decodeFile(strPath); imageView.setImageBitmap(bm);

con

final BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 8; Bitmap bm = BitmapFactory.decodeFile(strPath,options); imageView.setImageBitmap(bm);

Use inSampleSize para cargar escalas de mapas de bits en la memoria. El uso de potencias de 2 para los valores de inSampleSize es más rápido y más eficiente para el decodificador. Sin embargo, si planea almacenar en caché las versiones redimensionadas en la memoria o en el disco, generalmente vale la pena decodificarlas a las dimensiones de imagen más adecuadas para ahorrar espacio.

Para más información, vea Cómo cargar developer.android.com/training/displaying-bitmaps/…


Utilice esto en el archivo de manifiesto en la etiqueta de la aplicación

android:largeHeap="true"


Yo tuve el mismo problema. Incorporé todas las sugerencias anteriores, pero todavía tenía el problema de java.lang.outOfMemoryError. Después de muchos ajustes, lo que finalmente funcionó fue reducir las dimensiones (y el tamaño) de la imagen. Originalmente, tenía imágenes de dimensiones de 800 x 1000 clases. Los realicé a aproximadamente 60 x 80 (porque eso es lo que necesitaba), ¡y funcionó!

Así que, además de seguir todos los consejos sobre este problema que se encuentran en y otros sitios, también realice una comprobación de base de los tamaños y dimensiones de sus imágenes. Te ahorrará mucho dolor de cabeza.