Android 使用帧动画内存溢出解决方案
最近在项目遇到的动画效果不好实现,就让UI切成图,采用帧动画实现效果,但是在使用animation-list时,图片也就11张,每张图片大概560k左右,结果内存溢出,崩溃 了,自己用了三张都崩溃;拿代码说;
1.anin_searh.xml
<&#63;xml version="1.0" encoding="utf-8"&#63;>
2.使用帧动画
search_scale_iv.setBackgroundResource(R.drawable.anim_search); AnimationDrawable drawable = (AnimationDrawable) search_scale_iv.getBackground(); drawable.start();
结果setBackgroundResource出现内存溢出,这个方法其实获取drawable时候,会消耗很多内存,很容易内存溢出,崩溃。
3.解决方法:在网上找了个类,处理,结果我使用11张560k大小图片,没有内存溢出;
import android.content.Context; import android.content.res.XmlResourceParser; import android.graphics.BitmapFactory; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Handler; import android.widget.ImageView; import org.apache.commons.io.IOUtils; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /**** * 此工具类源于stack over flow * 原文链接:http://stackoverflow.com/questions/8692328/causing-outofmemoryerror-in-frame-by-frame-animation-in-android * 主要使用了BitmapFactory.decodeByteArray方法通过底层C来绘制图片,有效防止OOM * 使用了第三方类库:org.apache.commons.io.IOUtils,将Inputstream转为byte字节数组 * *******/ public class MyAnimationDrawable { public static class MyFrame { byte[] bytes; int duration; Drawable drawable; boolean isReady = false; } public interface OnDrawableLoadedListener { public void onDrawableLoaded(ListmyFrames); } // 1 /*** * 性能更优 * 在animation-list中设置时间 * **/ public static void animateRawManuallyFromXML(int resourceId, final ImageView imageView, final Runnable onStart, final Runnable onComplete) { loadRaw(resourceId, imageView.getContext(), new OnDrawableLoadedListener() { @Override public void onDrawableLoaded(List myFrames) { if (onStart != null) { onStart.run(); } animateRawManually(myFrames, imageView, onComplete); } }); } // 2 private static void loadRaw(final int resourceId, final Context context, final OnDrawableLoadedListener onDrawableLoadedListener) { loadFromXml(resourceId, context, onDrawableLoadedListener); } // 3 private static void loadFromXml(final int resourceId, final Context context, final OnDrawableLoadedListener onDrawableLoadedListener) { new Thread(new Runnable() { @Override public void run() { final ArrayList myFrames = new ArrayList (); XmlResourceParser parser = context.getResources().getXml( resourceId); try { int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_DOCUMENT) { } else if (eventType == XmlPullParser.START_TAG) { if (parser.getName().equals("item")) { byte[] bytes = null; int duration = 1000; for (int i = 0; i myFrames, ImageView imageView, Runnable onComplete) { animateRawManually(myFrames, imageView, onComplete, 0); } // 5 private static void animateRawManually(final List myFrames, final ImageView imageView, final Runnable onComplete, final int frameNumber) { final MyFrame thisFrame = myFrames.get(frameNumber); if (frameNumber == 0) { thisFrame.drawable = new BitmapDrawable(imageView.getContext() .getResources(), BitmapFactory.decodeByteArray( thisFrame.bytes, 0, thisFrame.bytes.length)); } else { MyFrame previousFrame = myFrames.get(frameNumber - 1); ((BitmapDrawable) previousFrame.drawable).getBitmap().recycle(); previousFrame.drawable = null; previousFrame.isReady = false; } imageView.setImageDrawable(thisFrame.drawable); new Handler().postDelayed(new Runnable() { @Override public void run() { // Make sure ImageView hasn't been changed to a different Image // in this time if (imageView.getDrawable() == thisFrame.drawable) { if (frameNumber + 1
这里需要导入jar,
import org.apache.commons.io.IOUtils;
4.然后通过上述类,来调用自己的动画xml,
MyAnimationDrawable.animateRawManuallyFromXML(R.drawable.anim_search, search_scale_iv, new Runnable() { @Override public void run() { // TODO onStart // 动画开始时回调 log.d("","start"); } }, new Runnable() { @Override public void run() { // TODO onComplete // 动画结束时回调 log.d("","end"); } });
这样在使用帧动画时,可以有效的适度防止内存溢出,谁还有什么办法,欢迎交流!
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!