首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android如何在做帧动画的同时减小内存大小

Android如何在做帧动画的同时减小内存大小
EN

Stack Overflow用户
提问于 2015-12-10 14:18:47
回答 2查看 838关注 0票数 1

我正在执行帧动画和使用具有550*360分辨率的图像。我在某个地方读到,大图像应该被缩放到最小的大小和分辨率,因为1像素会将4字节的空间放入内存中。

我是一帧一帧地执行动画,但是当我从android内存分析器工具中检查它时,这会导致内存的大幅度增长,有时它会因为内存不足而崩溃。

,我知道这是由于图像的巨大大小,它被加载到内存中,但问题如下:

  1. 怎样才能安全地将图像加载到内存中,而不占用太多的空间。
  2. 如何在没有OOM错误的情况下进行帧动画?
  3. 假设我正在使用的动画虽然占用了太多的内存空间,但是动画最终没有任何问题,所以在执行动画之后,我如何从内存中卸载图像,因为它们已经完成了动画任务,现在它们是无用的?

请告诉我的方法,并提供源代码,如果你不能回答,那么请至少告诉我如何做我已经说过的第3点。因为这是容易的。

编辑这里是我是如何做我的动画(帧一帧)

代码语言:javascript
复制
public abstract class AnimationDrawableCallback implements Drawable.Callback {


private Drawable mLastFrame;


private Drawable.Callback mWrappedCallback;

/**
 * Flag to ensure that {@link #onAnimationComplete()} is called only once, since
 * {@link #invalidateDrawable(Drawable)} may be called multiple times.
 */
private boolean mIsCallbackTriggered = false;


public AnimationDrawableCallback(AnimationDrawable animationDrawable, Drawable.Callback callback) {
    mLastFrame = animationDrawable.getFrame(animationDrawable.getNumberOfFrames() - 1);
    mWrappedCallback = callback;
}

@Override
public void invalidateDrawable(Drawable who) {
    if (mWrappedCallback != null) {
        mWrappedCallback.invalidateDrawable(who);
    }

    if (!mIsCallbackTriggered && mLastFrame != null && mLastFrame.equals(who.getCurrent())) {
        mIsCallbackTriggered = true;
        onAnimationComplete();
    }
}

@Override
public void scheduleDrawable(Drawable who, Runnable what, long when) {
    if (mWrappedCallback != null) {
        mWrappedCallback.scheduleDrawable(who, what, when);
    }
}

@Override
public void unscheduleDrawable(Drawable who, Runnable what) {
    if (mWrappedCallback != null) {
        mWrappedCallback.unscheduleDrawable(who, what);
    }
}




public abstract void onAnimationComplete();

}

对话框类,因为我在Dialog.中显示我的动画

代码语言:javascript
复制
    public class AnimationDialog extends Dialog  {


    public Activity c;
  //  public Dialog dialog;
//    public Button yes, no;
    ImageView mImageView;
    int mDrawable;
    AnimationDrawable countdownAnimation;
    Animation animationFalling;
    public AnimationDialog(Activity a, int drawable) {
        super(a);
        // TODO Auto-generated constructor stub
        this.c = a;
        this.mDrawable = drawable;
        getWindow().setWindowAnimations(R.style.DialogAnimation);
       // AnimationDialog.this.getWindow().getAttributes().windowAnimations = R.style.DialogSlideAnim;
    }

    @Override
    public void setOnCancelListener(OnCancelListener listener) {
        super.setOnCancelListener(listener);
        countdownAnimation = null;
        animationFalling = null;
        mImageView = null;
        c = null;
    }

    @Override
    public void dismiss() {
        super.dismiss();
        countdownAnimation = null;
        animationFalling = null;
        mImageView = null;
        c = null;
 //       dialog = null;



    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.custom_dialog);
        getWindow().setBackgroundDrawableResource(android.R.color.transparent);
        getWindow().setLayout(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
        getWindow().setGravity(Gravity.TOP);

        //this.setCancelable(false);

        mImageView = (ImageView) findViewById(R.id.iv_animation);

        mImageView.setBackgroundResource(mDrawable);

        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                //Do something after 100ms
                ((AnimationDrawable) mImageView.getBackground()).start();
                countdownAnimation = (AnimationDrawable) mImageView.getBackground();
                countdownAnimation.setCallback(new AnimationDrawableCallback(countdownAnimation, mImageView) {
                    @Override
                    public void onAnimationComplete() {
                        // TODO Do something.
//                        Toast.makeText(c, "Animation Ended", Toast.LENGTH_SHORT).show();
                        TextView tv = (TextView) findViewById(R.id.tv);
                        Button btn = (Button) findViewById(R.id.close);
                        RelativeLayout rl = (RelativeLayout) findViewById(R.id.secondry_frame);
                        animationFalling = AnimationUtils.loadAnimation(c, R.anim.anim_falling);
                        rl.startAnimation(animationFalling);
                        tv.setVisibility(View.VISIBLE);
                        btn.setVisibility(View.VISIBLE);
                        btn.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {

                                countdownAnimation = null;
                                animationFalling=null;
                                countdownAnimation = null;
                                AnimationDialog.this.cancel();
                                dismiss();
                               // AnimationDialog.this.dismiss();
//                                countdownAnimation = null;

                            }
                        });
                    }
                });
                countdownAnimation.start();

                // Toast.makeText(Alif.this,"Please start from the word Top",Toast.LENGTH_SHORT).show();
            }
        }, 1500);
   }
  }

和可绘图:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>

代码语言:javascript
复制
<item
    android:drawable="@drawable/rolling_1"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_2"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_3"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_4"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_5"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_6"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_7"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_8"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_9"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_10"
    android:duration="300" />
<item
    android:drawable="@drawable/rolling_11"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_12"
    android:duration="300" />
<item
    android:drawable="@drawable/rolling_13"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_14"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_15"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_16"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_17"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_18"
    android:duration="300" />

<item
    android:drawable="@drawable/rolling_19"
    android:duration="300" />

,在活动中,我称之为

代码语言:javascript
复制
 animationDialog = new AnimationDialog(Main.this, R.drawable.my_animation);
                            animationDialog.show();
EN

回答 2

Stack Overflow用户

发布于 2015-12-10 14:24:14

您应该在onDestroy方法上实现一些东西。我的意思是,您应该在onDestroy中将动画的引用设置为null。这就是我现在想的,因为你没有提供适当的细节。

代码语言:javascript
复制
@Override
    protected void onDestroy() {

//set your refernce of animation class or what ever you using to null

}
票数 0
EN

Stack Overflow用户

发布于 2015-12-10 15:43:42

您应该释放旧的映像来释放内存,并且只在它们即将显示时加载它们。例如,默认情况下,Android中的ViewPager只在内存中加载3页:可见的页面、前一个页面和下一个页面。当你滑动到下一页时,前一页将被删除,新的-下一页将被加载。

此外,您能提供如何加载图像和如何执行动画的来源吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34204206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档