2011-08-12 16 views
18

Según tengo entendido (no es que esté en lo cierto) Los drenajes generalmente se eliminan correctamente de la memoria cuando la aplicación termina con ellos. Sin embargo, los mapas de bits deben reciclarse manualmente y, a veces, incluso tienen una clase especial escrita para manejarlos correctamente. Mi pregunta es, en lo que respecta a la memoria y las fugas, es más beneficioso simplemente seguir con dibujables como tales:Drawable vs Single ¿Bitmap reutilizable mejor con memoria?

myView.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image)); 
myView1.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image1)); 
myView2.setBackgroundDrawable(getResources().getDrawable(R.drawable.my_image2)); 

en lugar de algo así como de mapas de bits:

Bitmap tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image); 
myView.setImageBitmap(tmpBitmap); 

tmpBitmap.recycle(); 
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image1); 
myView1.setImageBitmap(tmpBitmap); 

tmpBitmap.recycle(); 
tmpBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image2); 
myView2.setImageBitmap(tmpBitmap); 
tmpBitmap.recycle(); 

tengo ¿También lees, por supuesto, que debes tener cuidado con el método recycle() en Bitmaps porque pueden eliminarse mientras aún están en uso? Parece que estos problemas siguen apareciendo en diferentes formas, pero realmente no puedo obtener una respuesta directa de nadie sobre el asunto. A una persona le dice a reutilizar y reciclar un mapa de bits después de cada uso, y otros dicen dibujables de uso y un método unbindDrawables() (esto es lo que he estado usando):

private void unbindDrawables(View view) { 
    if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
     ((ViewGroup) view).removeAllViews(); 
    } 
} 

Cualquier penetración aplicable sería muy apreciada aunque . Gracias

Respuesta

8

Respaldo la propuesta de Romain, pero no estoy seguro de que su pregunta aborde su problema real. No sé cómo manejas las referencias a tus Vistas. Tal vez simplemente tiene pérdidas de memoria en su aplicación? Una gran cantidad de pérdidas de memoria en Android están relacionadas con Context. Cuando se conecta un Drawable a un View, el View se configura como una devolución de llamada en el Drawable.

TextView myView = new TextView(this); 
myView.setBackgroundDrawable(getDrawable(R.drawable.my_bitmap)); 

En el fragmento de código anterior, esto significa que el Drawable tiene una referencia a la TextView que a su vez tiene una referencia a la Activity (el Context) que a su vez tiene referencias a casi cualquier cosa dependiendo de su código.

Sin mirar más de su código, supongo que está en el camino correcto estableciendo las devoluciones de llamadas almacenables almacenadas en null cuando se destruye Activity.

+0

gracias, muy buena información. Obtengo mis puntos de vista a través de findViewById (R.Id.Image_name); por cierto. No estoy seguro de si esto de alguna manera deja referencias al contexto o no. –

9

Bitmaps no necesita para ser reciclado manualmente. Son basura recogida como Drawables y otros objetos. Del mismo modo, no es necesario desvincular a los dibujables, excepto en situaciones muy específicas. Parece que lees mucha información engañosa.

mapas de bits de reciclaje y disponibles compromiso.Por pueden ser útiles en algunas situaciones (por ejemplo, si su aplicación manipular grandes cantidades de datos de mapa de bits o si almacena estirable de manera estática.)

Los dos ejemplos que muestran al principio de tu pregunta son equivalentes. Si carga un dibujable directamente, los mapas de bits se cargarán en su nombre. Si carga mapas de bits manualmente y los establece en un ImageView, se incluirán en los modelos en su nombre.

Utilice la primera solución ya que es más simple y no se preocupe por la desvinculación y otras técnicas de administración de memoria hasta que realmente las necesite.

+0

Bueno, la razón por la que pregunto es porque necesito técnicas de administración de memoria. Manipulo las imágenes de múltiples vistas con solo hacer clic en un botón, y este es mi sistema de menú. Está bien, a menos que pase por cada menú, luego salga y vuelva a hacerlo todo. Después de algunas veces, la aplicación se bloquea debido a que "Mapa de bits excede el OOM de límite de VM".No estoy seguro de por qué hace esto, pero cuando uso el método unbindDrawables() no sucede. O al menos no he podido recrearlo todavía. –

+3

Tienes que ser MUY cuidadoso antes de Honeycomb sobre bitmaps. Los mapas de bits Pre-Honeycomb se asignan en un espacio RAM que el recolector de basura de Java no puede alcanzar. Esto conduce a pérdidas de memoria. Si estás en Honeycomb y luego estás en lo cierto. –

+1

El hecho de que los mapas de bits se hayan asignado en el montón nativo no provocó pérdidas de memoria. Simplemente significaba que tendrías que esperar a que se ejecutaran los finalizadores antes de que se liberara el mapa de bits. –

Cuestiones relacionadas