Red de conocimientos sobre prescripción popular - Conocimiento dental - Cómo solucionar el desbordamiento de memoria en la animación de fotogramas de Android

Cómo solucionar el desbordamiento de memoria en la animación de fotogramas de Android

1.anin_searh.xml

[html]Ver texto sin formato

& lt? versión xml = "1.0" codificación = "utf-8"? & gt

& lt lista de animaciones xmlns:Android = "/apk/RES/Android "

Android:one shot = " true " & gt;

& litem Android:drawable = " @ drawable/a 1 " Android:duration = " 100 " & gt;& lt/item & gt;

& litem Android:drawable = " @ drawable/a2 " Android:duración = " 100 " & gt; & gt;

& litem Android:drawable = " @ drawable/a5 " Android:duración = " 100 " & gt;& lt/item & gt;

& litem Android: drawable = " @ drawable/a6 " Android:duration = " 100 " & gt;& lt/item & gt;

& litem Android:drawable = " @ drawable/a7 " Android:duration = " 100 " & gt;& lt/item & gt;

& litem Android:drawable = " @ drawable/A8 " Android:duration = " 100 " & gt; & lt/item & gt;

& litem Android:drawable = " @ drawable/a9 " Android:duration = " 100 " & gt;& lt/item & gt;

& litem Android:drawable = " @ drawable/ a 10 " Android:duration = " 100 " & gt; & lt/item & gt;

& litem Android:drawable = " @ drawable/a 11 " Android:duration = " 100 " >; & lt/item & gt;

& lt/animation-list & gt;

2. >[java]Ver texto sin formato

search _ scale _ iv . setbackgroundresource(r . drawable . anim _ search

AnimationDrawable drawable =(AnimationDrawable)search _ scale _ iv . get background();

drawable .start();

Por lo tanto, hay un desbordamiento de memoria en setBackgroundResource.

De hecho, este método consume mucha memoria al obtener el elemento de diseño y es propenso a desbordarse y fallar.

3. Solución: encontré una clase en Internet y la solucioné. Como resultado, utilicé 11 imágenes de tamaño 560k y no hubo desbordamiento de memoria;

[java] Ver texto sin formato

Importar contenido de Android;

.

Importar contenido de Android. RES. Analizador de recursos XML;

Importar gráficos de Android.

Importar gráficos dibujables de Android. p>Importar gráficos de Android. Dibujables.

Importar gráficos de Android. .widget.imageview;

Importar org.Apache.commons.io.ioutils;

Importar org.xmlpull.v1. XmlPullParser

Importa org.xmlpull.v1. XmlPullParserException

Importar Java io .io excepción;

Importar Java util . >/****

*Esta clase de utilidad se origina en el flujo de desbordamiento de la pila.

*Enlace original:/questions/8692328/error de falta de memoria-en-animación-cuadro-a-cuadro-en-Android.

* El método BitmapFactory.decodeByteArray se utiliza principalmente para dibujar imágenes a través de C subyacente, lo que previene eficazmente OOM.

*Utilice la biblioteca de clases de terceros: org.apache.commons.io.IOUtils para convertir el flujo de entrada en una matriz de bytes.

* *******/

Clase pública MyAnimationDrawable {

Clase estática pública MyFrame {

byte[] palabra sección;

int duración;

dibujable;

boolean isReady = false

}

Interfaz pública de OnDrawableLoadedListener {

public void onDrawableLoaded(List & lt; MyFrame & gtmy frames

}

// 1

/*); **

*Mejor rendimiento

*Establecer tiempo en la lista de animaciones.

* **/

public static void animaterawmanullyfromxml(int ResourceId,

Vista de imagen final, finalmente ejecutable al iniciar,

Finalmente ejecute onComplete) {

loadRaw(resourceId, imageView.getContext(),

new OnDrawableLoadedListener() {

@override

public void onDrawableLoaded(List & lt; MyFrame & gtmyFrames) {

If (onStart!= null) {

onstart run();

}<. /p>

animateRawManually(myFrames, imageView, completo);

}

});

}

/ / 2

Carga vacía estática privadaRaw(final int ResourceId, contexto de contexto final,

final OnDrawableLoadedListener OnDrawableLoadedListener){

loadFromXml(resourceId, contexto, onDrawableLoadedListener);

}

// 3

Carga vacía estática privadaFromXml(final int ResourceId,

Contexto de contexto final,

final OnDrawableLoadedListener OnDrawableLoadedListener){

nuevo hilo(nuevo Runnable() {

@override

public void run(){

Lista de matriz final & ltMyFrame & gtmyFrames = new ArrayList & ltMyFrame & gt();

Analizador de recursos XML = contexto .obtener recursos().

resourceId ;

Prueba {

int tipo de evento = parser . get tipo de evento();

mientras (eventType! =XmlPullParser. END_DOCUMENT) {

if (eventType == XmlPullParser.START_DOCUMENT) {

} else if(event type == XML pull parser.START_TAG) {

if (parser.getName().equals("item")) {

byte[]bytes = null;

int duración = 1000;

for( int I = 0;i<parser.getAttributeCount();i++) {

if (parser.getAttributeName(i)).

es igual(

" dibujable")) {

int resId = Integer.parseInt(parser

.getAttributeValue(i)

. subcadena(1));

bytes = IOUtils.toByteArray(context

.getResources()

.openraw recurso(resId));

p>

} else if(parser . getattributename(I)

. es igual a ("duración"){

duración = parser . getattributeintvalue(

i, 1000);

}

}

mi marco mi marco = nuevo mi marco();

myFrame.bytes = bytes

myFrame.duration =duración;

mis marcos . add(mi marco);

}

} else if (tipo de evento == analizador de extracción XML. END_TAG) {

} else if (tipo de evento == analizador de extracción XML. texto) {

}

tipo de evento = analizador . next();

}

} catch (IOException e) {

e . p> } catch(XmlPullParserException E2){

// TODO: Manejar excepciones

E2 . printstacktrace();

}

// Ejecuta un nuevo controlador (context.getMainLooper()) en el hilo de la interfaz de usuario.

post(new Runnable() {

@override

public void runnable(){

if (onDrawableLoadedListener!= null) {

ondrawableloadedlistener .ondrawableloaded(mis marcos);

}

}

});

}

}).run();

}

// 4

Animador de vacío estático privado manualmente(List<MyFrame>MyFrame,

ImageView imageView, se puede ejecutar onComplete) {

animateRawManually(myFrames, imageView, onComplete, 0);

}

// 5

AnimateRawManually de vacío estático privado (lista final<MyFrame>MyFrame,

Vista de imagen final, ejecutable final completo,

Número de fotograma final){

final mi fotograma este fotograma = mis marcos get(número de fotograma);

if (frameNumber == 0) {

este fotograma dibujable = new BitmapDrawable(imageview. get context()

.getResources(), BitmapFactory.decodeByteArray(

thisFrame.bytes, 0, este marco. bytes. longitud));

p>

}En caso contrario {

mi marco marco anterior = mis marcos. get(número de marco-1);

((BitmapDrawable)marco anterior. dibujable). obtener mapa de bits(). recycle();

previousFrame.drawable = null

el marco anterior está listo = false;

}

imageview. este marco. dibujable);

Nuevo controlador().

postDelayed(new Runnable() {

@Override

public void Runnable(){

//Asegúrate de que ImageView no se haya cambiado a una imagen diferente

//En este momento

if(imageview. get drawable()= = este marco. dibujable){

if(número de marco+1 & lt ;myFrames.size()) {

mi fotograma siguiente fotograma = mis fotogramas get(número de fotograma+1);

if (nextFrame.isReady) {

/ /Crear el siguiente cuadro de animación

Manual de animación (myFrames, imageView, onComplete,

número de cuadro+1

} De lo contrario {

el siguiente fotograma está listo = verdadero;

}

}else{

if (onComplete!= null) {

al completar la ejecución();

}

}

}

}

}, duración de este fotograma);

//Carga el siguiente fotograma

if(número de fotograma+1 & lt;myFrames.size()) {

Nuevo hilo( new Runnable() {

@override

public void runnable(){

mi fotograma siguiente fotograma = mis fotogramas. get(número de fotograma +1);

siguiente cuadro . drawable = new BitmapDrawable(imageView

.getContext().getResources(),

bitmapfactory .decodebytearray(siguiente cuadro . bytes, 0,

siguiente fotograma. bytes de longitud));

if (nextFrame.isReady) {

//Crea el siguiente fotograma de animación

Manual de animación(myFrames, imageView, onComplete,

número de fotograma+1

} De lo contrario, {

el siguiente fotograma está listo. = verdadero;

p>

}

}

}).run();

}

}