"Lienzo: tratando de dibujar un mapa de bits demasiado grande" cuando el Tamaño de pantalla de Android N se establece en un tamaño mayor que Pequeño

81

Tengo una aplicación publicada que se bloquea al inicio en Android N cuando la Display sizeconfiguración del sistema operativo recién introducida está configurada en un valor demasiado grande.

Cuando miro en logcat, veo el siguiente mensaje:

java.lang.RuntimeException: Canvas: trying to draw too large(106,975,232 bytes) bitmap.

He rastreado el problema hasta un ImageView en mi primera actividad que muestra una imagen de fondo grande y agradable. La imagen en cuestión es 2048x1066 y está en mi drawablesdirectorio genérico , por lo que no importa la densidad, se utilizará esta imagen.

Todo funciona bien cuando el Display sizeentorno es Small. Pero cuando subo Default, deja de funcionar. Si luego cambio la imagen por una más pequeña, funciona Default, pero si subo Large, deja de funcionar nuevamente.

Supongo que el ajuste Display sizehace que su dispositivo se comporte como un dispositivo físicamente más pequeño con una mayor densidad de píxeles. Pero no entiendo qué se supone que debo hacer aquí. Si coloco imágenes cada vez más pequeñas para resoluciones progresivamente más altas, no se verá bien en pantallas realmente grandes. ¿O no estoy entendiendo algo?

Cualquier sugerencia será muy apreciada.

Brian Rak
fuente
23
"La imagen en cuestión es 2048x1066 y está en mi directorio genérico de elementos de diseño, así que no importa la densidad, esta imagen se utilizará" - res/drawable/es un sinónimo de res/drawable-mdpi/. Si desea que la imagen no se escale según la densidad, use res/drawable-nodpi/ores/drawable-anydpi/ .
CommonsWare
3
"¿Está diciendo que una imagen de 100 x 100 píxeles que vive en varios directorios de recursos diferentes se escala en realidad para crear una versión virtual de resolución diferente antes de pasar al diseño?" - eso depende de las densidades que tenga y del dispositivo en el que esté ejecutando. Si hay una coincidencia exacta, no se vuelve a muestrear nada. Si no hay una coincidencia exacta, se vuelve a muestrear la imagen de una densidad cercana. Entonces, si solo tiene res/drawable/foo.png(también conocido como, res/drawable-mdpi/foo.png), y su dispositivo lo tiene xhdpi, la imagen se duplicará a lo largo de ambos ejes, ocupando 4 veces la memoria.
CommonsWare
4
El valor de 106975232 en su error resulta ser exactamente 49 veces la resolución de la imagen, lo que implica un remuestreo de 7 veces en ambos ejes. Eso es mucho más alto de lo que esperaba. Todavía no tuve la oportunidad de jugar con la configuración de tamaño de pantalla en Android 7.0, así que lo
agregaré
6
¡Buena captura en el 49x! Creo que puedo explicar por qué es tan alto. Tenga en cuenta que ese número son bytes. Esta imagen es de 24 bits, pero probablemente se lea a 32 bits por píxel. Eso lo haría 8732672 bytes en la memoria, lo que entra en esa cifra exactamente 12,25 veces, lo que a su vez implica una escala de 3,5x a lo largo de cada eje. Este dispositivo es xxhdpi, por lo que parece que está bien. De cualquier manera, no tenía idea de que los recursos se volverían a muestrear de esa manera. ¡Gracias por la ayuda! (Por cierto, mover la imagen a drawable-nodpi realmente lo arregla).
Brian Rak
1
Realmente debería aceptar la respuesta de johan
S. Jacob Powell

Respuestas:

166

Yo mi caso, moviendo la (alta resolución) de mapa de bits salpicaduras de dibujable a dibujable-xxhdpi era la solución.

Yo tuve el mismo problema. No sospeché que mi pantalla de bienvenida fuera el problema, ya que se muestra cuando se inicia la aplicación, pero resultó que la pantalla de bienvenida es el problema.

La pantalla de bienvenida en mi caso tiene una resolución xxhdpi, y se colocó por error en el dibujable carpeta, en lugar de dibujable-xxhdpi . Esto hizo que Android asumiera que la pantalla de presentación tenía una resolución de mdpi y escalar la imagen a 3 * 3 veces su tamaño requerido y tratar de crear un mapa de bits.

Johan Franzén
fuente
Supongo: entonces, ¿Android escala una imagen de xxhdpi a hdpi, por ejemplo, para que sea una imagen más clara? como dijiste de 3 * 3 -> 1/1 a 1/3 por ejemplo?
Codificación Ninja
Como señala kalsara Magamage, ahora es mipmap-xxhdpi.
Dana Robinson
35

Resolví el problema después de agregar el siguiente código en la etiqueta de aplicación del archivo Manifest entre android: líneas.

android:hardwareAccelerated="false"
CHAMCHOUN
fuente
3
Bueno, después de pasar algunas horas esta solución funciona para problemas móviles xiaomi y Samsung.
Shihab Uddin
3
Esto resultará en la desactivación de todas las elevaciones de CardView. Entonces, la solución adecuada sería escalar el mapa de bits a un tamaño más pequeño.
Sachin Soma
En lugar de deshabilitar la aceleración de hardware en el nivel de Aplicación, controlarla en Actividad, Ventana, Vista será más útil.
Mukhammadsher
Pero, hay algún otro problema que surge después de hacerlo android:hardwareAccelerated="false" . mostrando una vista extraña en algún dispositivo que tiene un nivel de API por debajo de 22.
Prince Dholakiya
No hagas eso, ralentiza tu aplicación.
Curio
11

No sé si ayudaría a alguien, pero lo dejaré aquí. En mi caso, el problema estaba solo en los dispositivos Sumsung con Android 7 y el problema estaba en las proporciones de la pantalla de inicio. después de cambiar la altura a 1024 px, todo funciona bien

kazimad
fuente
Mi problema fue el mapa de bits (jpg, png) en la carpeta dibujable (sin sufijo). Es mi estupidez, pero tal vez ayude a alguien :-)
gingo
¡Esto es útil! El mismo problema solo Samsung ... ¿Qué tuvo primero y cómo lo solucionó?
M'hamed
¿Estabas intentando cargar las imágenes desde la URL? Estoy enfrentando el mismo problema solo con Samsung Galaxy S6 en Android 7. Estoy cargando imágenes en RecyclerView. Todavía no puedo resolver esto. @ M'hamed
Rohit Singh
9

Mueva su imagen en el dibujable a mipmap-xxhdpi. Su imagen está en formato de mapa de bits, por lo que debe poner su imagen en la carpeta mipmap, luego funcionará

kalsara Magamage
fuente
1
AFAIK, la carpeta mipmap es solo para los iconos del iniciador. Nunca lo he usado para otra cosa. Ver stackoverflow.com/a/28065664/4034572
Albert Vila Calvo
Sí, esto funcionó para mí. Tenía imágenes de aproximadamente 1 MB y las puse en mipmap-xxhdpi
3

si usa Picasso, cambie a Glide así.

Quitar picasso

Picasso.get().load(Uri.parse("url")).into(imageView)

Cambiar planeo

Glide.with(context).load("url").into(imageView)

Más eficiente

Deniz
fuente
Sigo recibiendo el error incluso después de cambiar a Glide desde Picasso. En el teléfono Samsung J6. Y Moto Z2 :(
Rohit Singh
1

Hay algunos escenarios en los que el mapa de bits original debe dibujarse en ImageViews, aplicaciones de edición de fotos, etc.

como la bahía mencionada anteriormente

android:hardwareAccelerated="false"

Causará una mala experiencia en la interfaz de usuario, puede configurar acelerado por hardware Solo una actividad seleccionada donde se dibujará una imagen de alta resolución

<application android:hardwareAccelerated="true">
    <activity ... />
    <activity android:hardwareAccelerated="false" />
</application>
Balu mallisetty
fuente
1

Revisé el Logcat

Proceso: co.coolresume, PID: 11145 java.lang.RuntimeException: Canvas: tratando de dibujar un mapa de bits demasiado grande (572166144bytes). en android.view.DisplayListCanvas.throwIfCannotDraw (DisplayListCanvas.java:229) en android.view.RecordingCanvas.drawBitmap (RecordingCanvas.java:97) en android.graphics.drawable.BitmapDrawable.draw (BitmapDrawable.java .529) widget.ImageView.onDraw (ImageView.java:1367) en android.view.View.draw (View.java:19380)

Resolví el error usando el siguiente manifiesto.

 <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:hardwareAccelerated="false">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>
Jose antonio
fuente
0

Los archivos de iconos son demasiado grandes para que Android los cargue de manera eficiente y sin problemas. Android reconoce esto con sus algoritmos inteligentes.

Puede cambiar el tamaño de los archivos de iconos usando Final Android Resizer por asystat. Cambie su tamaño a "xhdpi" o menor.

Coloque las fotos redimensionadas en dibujables o sobrescríbalas sobre los archivos de iconos grandes existentes.

Entonces, ya está.

lloydyu24
fuente
0

Si está usando deslizamiento y está cargando 1k de imágenes a la vez o algunas imágenes, entonces es cuestión de deslizamiento o lo que sea que esté haciendo para configurar la vista de imagen. puede resolverlo simplemente aplicando el tipo de escala en deslizamiento.

Deepak Rajput
fuente
0

se resuelve cambiando el tamaño de las imágenes a un tamaño menor.

HosseinRezaie
fuente