android帧动画太多太卡(OOM)解决方案

来源:互联网 发布:网络播音设备 编辑:程序博客网 时间:2024/04/29 18:41

IO工具类下载
- 使用方法

    private void initGif() {         ivShowGif = (ImageView) view.findViewById(R.id.ivShowGif);        /**         * 弃用系统自带帧动画导致的性能占用。改用handler         */        MyAnimationDrawable.animateRawManuallyFromXML(R.drawable.anim_gift_forgif, ivShowGif,                new Runnable() {                    @Override                    public void run() {                        // TODO onStart                    }                }, new Runnable() {                    @Override                    public void run() {                        // TODO onComplete                    }                });```} - 工具类<div class="se-preview-section-delimiter"></div>

package com.rex.p2pyichang.utils.gif;

/**
* Created by Rex on 2017/3/30.
*/

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

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;

/**
* 此工具类源于stack over flow
* 原文链接:http://stackoverflow.com/questio … nimation-in-android
* 主要使用了BitmapFactory.decodeByteArray方法通过底层C来绘制图片,有效防止OOM
* 使用了第三方类库:org.apache.commons.io.IOUtils,将Inputstream转为byte字节数组
*/
public class MyAnimationDrawable {

private static boolean isLooper;public static class MyFrame {    byte[] bytes;    int duration;    Drawable drawable;    boolean isReady = false;}public interface OnDrawableLoadedListener {     void onDrawableLoaded(List<MyFrame> myFrames);}/*** * 在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<MyFrame> myFrames) {                    if (onStart != null) {                        onStart.run();                    }                    animateRawManually(myFrames, imageView, onComplete);                }            });}private static void loadRaw(final int resourceId, final Context context,                            final OnDrawableLoadedListener onDrawableLoadedListener) {    loadFromXml(resourceId, context, onDrawableLoadedListener);}private static void loadFromXml(final int resourceId,                                final Context context,                                final OnDrawableLoadedListener onDrawableLoadedListener) {    new Thread(new Runnable() {        @Override        public void run() {            final ArrayList<MyFrame> myFrames = new ArrayList<MyFrame>();            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("oneshot")) {                            isLooper = parser.getAttributeBooleanValue(0, true);                        }                        if (parser.getName().equals("item")) {                            byte[] bytes = null;                            int duration = 1000;                            for (int i = 0; i < parser.getAttributeCount(); i++) {                                if (parser.getAttributeName(i).equals(                                        "drawable")) {                                    int resId = Integer.parseInt(parser                                            .getAttributeValue(i)                                            .substring(1));                                    bytes = IOUtils.toByteArray(context                                            .getResources()                                            .openRawResource(resId));                                } else if (parser.getAttributeName(i)                                        .equals("duration")) {                                    duration = parser.getAttributeIntValue(                                            i, 1000);                                }                            }                            MyFrame myFrame = new MyFrame();                            myFrame.bytes = bytes;                            myFrame.duration = duration;                            myFrames.add(myFrame);                        }                    } else if (eventType == XmlPullParser.END_TAG) {                    } else if (eventType == XmlPullParser.TEXT) {                    }                    eventType = parser.next();                }            } catch (IOException e) {                e.printStackTrace();            } catch (XmlPullParserException e2) {                // TODO: handle exception                e2.printStackTrace();            }            // Run on UI Thread            new Handler(context.getMainLooper()).post(new Runnable() {                @Override                public void run() {                    if (onDrawableLoadedListener != null) {                        onDrawableLoadedListener.onDrawableLoaded(myFrames);                    }                }            });        }    }).run();}// 4private static void animateRawManually(List<MyFrame> myFrames,                                       ImageView imageView, Runnable onComplete) {    animateRawManually(myFrames, imageView, onComplete, 0);}// 5private static void animateRawManually(final List<MyFrame> 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 < myFrames.size()) {                    MyFrame nextFrame = myFrames.get(frameNumber + 1);                    if (nextFrame.isReady) {                        // Animate next frame                        animateRawManually(myFrames, imageView, onComplete,                                frameNumber + 1);                    } else {                        nextFrame.isReady = true;                    }                } else {                    animateRawManually(myFrames, imageView, onComplete,                           0);                    if (onComplete != null) {                        onComplete.run();                    }                }            }        }    }, thisFrame.duration);    // Load next frame    if (frameNumber + 1 < myFrames.size()) {        new Thread(new Runnable() {            @Override            public void run() {                MyFrame nextFrame = myFrames.get(frameNumber + 1);                nextFrame.drawable = new BitmapDrawable(imageView                        .getContext().getResources(),                        BitmapFactory.decodeByteArray(nextFrame.bytes, 0,                                nextFrame.bytes.length));                if (nextFrame.isReady) {                    // Animate next frame                    animateRawManually(myFrames, imageView, onComplete,                            frameNumber + 1);                } else {                    nextFrame.isReady = true;                }            }        }).run();    }}

}

“`

1 0
原创粉丝点击