Current location - Plastic Surgery and Aesthetics Network - Plastic surgery and beauty - How to Solve Memory Overflow in Android Frame Animation
How to Solve Memory Overflow in Android Frame Animation
1.anin_searh.xml

[html] view plain text

& lt? Xml version =" 1.0 "encoding ="utf-8"? & gt

& lt Animation-List xmlns: Android = "/apk/res/Android"

Android:one shot = " true " & gt;

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

& ltitem Android:drawable = " @ drawable/a2 " Android:duration = " 100 " & gt; & lt/item & gt;

& ltitem Android:drawable = " @ drawable/a4 " Android:duration = " 100 " & gt; & lt/item & gt;

& ltitem Android:drawable = " @ drawable/a5 " Android:duration = " 100 " & gt; & lt/item & gt;

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

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

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

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

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

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

& lt/animation-list & gt;

2. Use frame animation

[java] View Plain Text

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

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

drawable . start();

Therefore, there is a memory overflow in setBackgroundResource. In fact, this method will consume a lot of memory when obtaining drawable, which is easy to overflow and crash.

3. Solution: I found a class on the Internet and handled it. Results I used 1 1 560k size pictures, and there was no memory overflow;

[java] View Plain Text

Import android.content.context;

Import android.content.res.xmlresourceparser;

Import android.graphics.bitmap factory;

Import android.graphics.drawable.animationdrawable;

Import android.graphics.drawable.bitmap drawable;

Import android.graphics.drawable.drawable;

Import android.os.handler;

Import android.widget.imageview;

Import org.apache.commons.io.ioutils;

Import org.xmlpull.v 1. XmlPullParser

Import org.xmlpull.v 1. XmlPullParserException

Import java.io.ioexception;

Import java.util.ArrayList;

Import java.util.list;

/****

* This tool class originates from the stack overflow stream.

* original link:/questions/8692328/reasoning-out of memory error-in-frame-by-frame-animation-in-Android.

* BitmapFactory.decodeByteArray method is mainly used to draw pictures through the underlying C, effectively preventing OOM.

* use the third-party class library: org.apache.commons.io.IOUtils to convert Inputstream into a byte array.

* *******/

Public class MyAnimationDrawable {

Public static class MyFrame {

Byte[] bytes;

Int duration;

Paintable;

boolean isReady = false

}

OnDrawableLoadedListener's public interface (

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

}

// 1

/***

* Better performance

* Set the time in the animation list.

* **/

public static void animaterawmanullyfromxml(int resourceId,

Final image view image view, and finally you can run onStart.

You can finally run onComplete) {

loadRaw(resourceId,imageView.getContext(),

new OnDrawableLoadedListener() {

@ Overlay

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

If (onStart! = null) {

onstart . run();

}

animateRawManually(myFrames,imageView,on complete);

}

});

}

// 2

Private static void loadRaw(final int resourceId, final Context context,

final OnDrawableLoadedListener OnDrawableLoadedListener){

loadFromXml(resourceId,context,onDrawableLoadedListener);

}

// 3

Private static void loadfrommxml (final int resourceid,

The final context context,

final OnDrawableLoadedListener OnDrawableLoadedListener){

New thread (new Runnable() {

@ Overlay

Public invalid operation () {

The final array list & lt myframe & gtmyframes = new ArrayList & lt myframe & gt ();

XML resource parser parser = context . get resources()。 getXml(

resourceId);

Try {

int event type = parser . get event type();

while (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 duration = 1000;

for(int I = 0; Me & ltparser. getattributecount (); i++) {

if (parser.getAttributeName(i))。 Equal to (

" drawable")) {

Int resId = Integer.parseInt (parser

. getAttributeValue(i)

. Substring (1));

Bytes = IOUtils.toByteArray (context

. getResources()

. openraw resource(resId));

} else if(parser . getattributename(I)

. Equal to ("duration") (

duration = parser . getattributeintvalue(

I,1000);

}

}

my frame my frame = new my frame();

myFrame.bytes = bytes

MyFrame.duration = duration;

my frames . add(my frame);

}

} else if(event type = = XML pull parser。 END_TAG) {

} else if(event type = = XML pull parser。 Text) {

}

event type = parser . next();

}

} catch (IOException e) {

e . printstacktrace();

} catch(XmlPullParserException E2){

// TODO: Handling exception

E2 . printstacktrace();

}

//Run on the UI thread

New handler (context.getMainLooper ()). post(new Runnable() {

@ Overlay

Public invalid operation () {

if (onDrawableLoadedListener! = null) {

ondrawableloadedlistener . ondrawableloaded(my frames);

}

}

});

}

}).run();

}

// 4

Private static void animator aw manually (list <: MyFrame & gt my frame,

ImageView imageView, which can run oncomplete) (

animateRawManually(myFrames,imageView,onComplete,0);

}

// 5

Private static void animateRawManually (final list & ltMyFrame & gt my frame,

The final image view, the image view, can finally be run,

Final frame number) (

final my frame this frame = my frames . get(frame number);

if (frameNumber == 0) {

this frame . drawable = new BitmapDrawable(imageview . get context()

. getResources(),BitmapFactory.decodeByteArray(

thisFrame.bytes,0,this frame . bytes . length));

} Otherwise {

my frame previous frame = my frames . get(frame number- 1);

((BitmapDrawable)previous frame . drawable)。 getBitmap()。 recycle();

previousFrame.drawable = null

previous frame . is ready = false;

}

imageview . setimagedrawable(this frame . drawable);

New handler (). postDelayed(new Runnable() {

@ Overlay

Public invalid operation () {

//Make sure that ImageView has not been changed to a different image.

//At this time

if(imageview . get drawable()= = this frame . drawable){

if(frame number+ 1 & lt; myFrames.size()) {

my frame next frame = my frames . get(frame number+ 1);

if (nextFrame.isReady) {

//Make the next frame of animation

Animation manual (myFrames, imageView, onComplete,

frame number+ 1);

} Otherwise {

next frame . is ready = true;

}

} Otherwise {

if (onComplete! = null) {

on complete . run();

}

}

}

}

},this frame . duration);

//Load the next frame

if(frame number+ 1 & lt; myFrames.size()) {

New thread (new Runnable() {

@ Overlay

Public invalid operation () {

my frame next frame = my frames . get(frame number+ 1);

next frame . drawable = new BitmapDrawable(imageView

. getContext()。 getResources(),

bitmapfactory . decodebytearray(next frame . bytes,0,

next frame . bytes . length));

if (nextFrame.isReady) {

//Make the next frame of animation

Animation manual (myFrames, imageView, onComplete,

frame number+ 1);

} Otherwise {

next frame . is ready = true;

}

}

}).run();

}

}