Android如何在制作帧动画时减少内存大小

Android如何在制作帧动画时减少内存大小,android,image,bitmap,android-animation,Android,Image,Bitmap,Android Animation,我正在执行帧动画并使用分辨率为550*360的图像。我在某个地方读到过,大图像应该缩放到最小大小和分辨率,因为1个像素占用内存4字节的空间 我正在执行逐帧动画,但这会导致内存大幅增长,因为我从android studio内存分析器工具检查它,有时它会由于内存不足错误而崩溃 我知道这是由于图像的巨大尺寸进入内存,但问题如下: 在不占用太多空间的情况下,将图像加载到内存中的安全方法是什么 如何在不出现OOM错误的情况下制作帧动画 假设我正在使用的动画虽然占用了太多的内存空间,但是动画最终没有任何问题

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

我正在执行逐帧动画,但这会导致内存大幅增长,因为我从android studio内存分析器工具检查它,有时它会由于内存不足错误而崩溃

我知道这是由于图像的巨大尺寸进入内存,但问题如下:

  • 在不占用太多空间的情况下,将图像加载到内存中的安全方法是什么

  • 如何在不出现OOM错误的情况下制作帧动画

  • 假设我正在使用的动画虽然占用了太多的内存空间,但是动画最终没有任何问题,那么,在执行动画后,我如何从内存中卸载图像,因为它们已经执行了动画任务,现在它们没有用了

  • 请告诉我方法并提供源代码,如果你不能回答,那么请至少告诉我如何做我在第3点中所述的事情。因为这个很容易

    编辑这里是我制作动画的方式(逐帧)

    }

    对话框类,因为我正在对话框中显示动画。

        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);
       }
      }
    
    <?xml version="1.0" encoding="utf-8"?>
    
     animationDialog = new AnimationDialog(Main.this, R.drawable.my_animation);
                                animationDialog.show();
    
    和可绘制的:

        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);
       }
      }
    
    <?xml version="1.0" encoding="utf-8"?>
    
     animationDialog = new AnimationDialog(Main.this, R.drawable.my_animation);
                                animationDialog.show();
    

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

    @Override
        protected void onDestroy() {
    
    //set your refernce of animation class or what ever you using to null
    
    }
    

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

    @Override
        protected void onDestroy() {
    
    //set your refernce of animation class or what ever you using to null
    
    }
    

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


    另外,您可以提供如何加载图像以及如何执行动画的来源吗?

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


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

    我知道这一点,我的基本想法也是这样,但没有帮助。我知道这一点,我的基本想法也是这样,但没有帮助。如何释放旧图像以释放内存?取决于你如何创建和存储它们。你能发布创作代码和动画代码吗?我已经更新了我的问题,现在检查一下哦。。。这是一个精灵动画。你能给我看看动画本身吗?也许有可能用另一种方式。例如,一个.gif文件或一幅图像中的一组帧?我不能,我不能这样做,因为我不知道,它只是一帧一帧的动画,让您感觉我们正在ImageView中对某些内容进行mving。如何释放旧图像以释放内存?取决于您如何创建和存储它们。你能发布创作代码和动画代码吗?我已经更新了我的问题,现在检查一下哦。。。这是一个精灵动画。你能给我看看动画本身吗?也许有可能用另一种方式。例如,一个.gif文件,或者一幅图像中的一组帧?我不能,我不能这样做,因为我不知道,它只是一帧一帧的动画,让您感觉我们正在imageview中对某些内容进行mving