【问题标题】:Animation with several big images带有几张大图的动画
【发布时间】:2014-09-24 08:52:30
【问题描述】:

你好,这是我的问题:

我必须在一个地方每 5 秒显示几张图像。问题是我使用的方法遇到了 OutOfMemory 致命异常

这里是完整的例外:

09-24 09:46:49.179: E/dalvikvm-heap(12289): Out of memory on a 14960016-byte allocation.
09-24 09:46:49.299: E/AndroidRuntime(12289): FATAL EXCEPTION: main
09-24 09:46:49.299: E/AndroidRuntime(12289): java.lang.RuntimeException: Unable to start activity ComponentInfo{ui.MainActivity}: android.view.InflateException: Binary XML file line #7: Error inflating class android.widget.ImageView
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread.access$700(ActivityThread.java:159)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.os.Looper.loop(Looper.java:137)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread.main(ActivityThread.java:5419)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at java.lang.reflect.Method.invokeNative(Native Method)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at java.lang.reflect.Method.invoke(Method.java:525)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1209)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1025)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at dalvik.system.NativeStart.main(Native Method)
09-24 09:46:49.299: E/AndroidRuntime(12289): Caused by: android.view.InflateException: Binary XML file line #7: Error inflating class android.widget.ImageView
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.createView(LayoutInflater.java:626)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.onCreateView(LayoutInflater.java:675)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:700)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:361)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.Activity.setContentView(Activity.java:1956)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at …ui.MainActivity.onCreate(MainActivity.java:111)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.Activity.performCreate(Activity.java:5372)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
09-24 09:46:49.299: E/AndroidRuntime(12289):    ... 11 more
09-24 09:46:49.299: E/AndroidRuntime(12289): Caused by: java.lang.reflect.InvocationTargetException
09-24 09:46:49.299: E/AndroidRuntime(12289):    at java.lang.reflect.Constructor.constructNative(Native Method)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.view.LayoutInflater.createView(LayoutInflater.java:600)
09-24 09:46:49.299: E/AndroidRuntime(12289):    ... 24 more
09-24 09:46:49.299: E/AndroidRuntime(12289): Caused by: java.lang.OutOfMemoryError
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:596)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:832)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.content.res.Resources.loadDrawable(Resources.java:2988)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.content.res.Resources.getDrawable(Resources.java:1558)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.drawable.AnimationDrawable.inflate(AnimationDrawable.java:282)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:937)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:873)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.content.res.Resources.loadDrawable(Resources.java:2970)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.widget.ImageView.<init>(ImageView.java:131)
09-24 09:46:49.299: E/AndroidRuntime(12289):    at android.widget.ImageView.<init>(ImageView.java:121)
09-24 09:46:49.299: E/AndroidRuntime(12289):    ... 27 more

现在我是这样做的:

[动画图像.xml]

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >

    <item
        android:drawable="@drawable/artistes"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/couple1"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/couple2"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/couple3"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/enfant"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/manege"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/manege2"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/metropolitain"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/panoramique"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/sacrecoeur"
        android:duration="5000"/>
    <item
        android:drawable="@drawable/velo"
        android:duration="5000"/>

</animation-list>

[MainActivity.java]

    ImageView mImageAnimation = (ImageView) findViewById(R.id.images);
    AnimationDrawable mAnimationDrawableImages = (AnimationDrawable) mImageAnimation.getDrawable();
    mAnimationDrawableEq.start();

[编辑 1]

我最终创建了一个调度程序类:

public class Scheduler {

    private OnScheduleTimeListener  mListener;
    private Handler                 mHandler;
    private int                     mInterval;          // Between each executions in milli
    private static final int        DELAY       = 100;  // before first execution
    private boolean                 mIsTimerRunning;
    private int                     mCount      = 0;
    private int                     mCountMax   = 1;
    private Mode                    mMode;

    public static enum Mode {
        ASC, // count
        DESC, // decount
    }

    public static interface OnScheduleTimeListener {

        public void onScheduleTime(int count);
    }

    /**
     * @param interval
     *        time interval between each loop in milli second
     * @param countMax
     *        maximum of itteration (-1 for infinite)
     * @param mode
     *        either ASC or DESC order
     */
    public Scheduler(int interval, int countMax, Mode mode) {
        super();
        if (countMax == -1) {
            mCountMax = Integer.MAX_VALUE;
        } else {
            if (mode.equals(Mode.DESC)) {
                mCount = countMax;
            }
            mCountMax = countMax;
        }
        mMode = mode;
        mInterval = interval;
        mHandler = new Handler();
    }

    private final Runnable  mRunnable   = new Runnable() {

                                            @Override
                                            public void run() {
                                                // Do stuff
                                                mListener.onScheduleTime(mCount);
                                                if (mMode.equals(Mode.ASC)) {
                                                    mCount++;
                                                } else {
                                                    if (mCount == 0) {
                                                        stopTimer();
                                                        return;
                                                    }
                                                    mCount--;
                                                }
                                                // Repeat
                                                mHandler.postDelayed(mRunnable, mInterval);
                                            }
                                        };

    public void setOnScheduleTimeListener(OnScheduleTimeListener listener) {
        mListener = listener;
    }

    public void startTimer() {
        mIsTimerRunning = true;
        mHandler.postDelayed(mRunnable, DELAY);
    }

    public void stopTimer() {
        mIsTimerRunning = false;
        mHandler.removeCallbacks(mRunnable);
    }

    public boolean isTimerRunning() {
        return mIsTimerRunning;
    }
}

【问题讨论】:

    标签: java android bitmap out-of-memory android-drawable


    【解决方案1】:

    不要使用 xml 来创建动画。创建一个将按需加载图像的视图。

    1. 加载图片 1 和图片 2。
    2. 5 秒后使用图片 2。
    3. 删除图片 1。
    4. 加载图片 3。

    例如(简单无预取):

    //I just wrote this here so there might be some errors
    
    static int images[] = new int[] {R.drawable.artistes, R.drawable.couple1, R.drawable.couple2}; //ETC intialize
    ImageView view; //initialize
    Handler handler; //initialize
    int index = 0;
    Runnable updater = new Runnable() {
        public void run() {
            if(index == images.length) {
                //animation is done
            }
            else {
                view.setImageResource(images[index++]);
                handler.postDelayed(this, 5000);
            }
        }
    };
    
    private void startAnimation() {
        handler.post(updater);
    }
    

    【讨论】:

    • 好的,我用你的想法得到了一个很好的解决方案,请参阅我的编辑并感谢 o/
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 2012-01-16
    • 2021-10-18
    • 1970-01-01
    • 2012-05-01
    • 2013-08-19
    相关资源
    最近更新 更多