[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();
}
}