Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不耗尽内存或使用非常小的图像的情况下加载多个AnimationDrawable?_Java_Android_Performance Testing - Fatal编程技术网

Java 如何在不耗尽内存或使用非常小的图像的情况下加载多个AnimationDrawable?

Java 如何在不耗尽内存或使用非常小的图像的情况下加载多个AnimationDrawable?,java,android,performance-testing,Java,Android,Performance Testing,我现在正在写一个应用程序,它使用四个占据大部分屏幕的主按钮。每一个都有三个动画:12帧介绍动画、33帧循环动画和基于单击循环的当前帧关闭的动画 图像高度大约在250到450之间。 在应用程序加载时加载所有这些内容不仅会导致初始加载缓慢,还会导致可用内存较小的设备出现内存不足异常 问题是,当我尝试加载动画而不预加载它们时,它会在加载之前跳过并挂起一秒钟。此外,我还注意到,即使在每次单击侦听器都需要活动动画时,内存使用量似乎也在20mb到40mb的堆大小之间 我并没有做任何奇怪的事情。我使用标准 A

我现在正在写一个应用程序,它使用四个占据大部分屏幕的主按钮。每一个都有三个动画:12帧介绍动画、33帧循环动画和基于单击循环的当前帧关闭的动画

图像高度大约在250到450之间。 在应用程序加载时加载所有这些内容不仅会导致初始加载缓慢,还会导致可用内存较小的设备出现内存不足异常

问题是,当我尝试加载动画而不预加载它们时,它会在加载之前跳过并挂起一秒钟。此外,我还注意到,即使在每次单击侦听器都需要活动动画时,内存使用量似乎也在20mb到40mb的堆大小之间

我并没有做任何奇怪的事情。我使用标准

AnimationDrawable animation = (AnimationDrawable)getResources().getDrawable(R.drawable.blah);
imageView.setImageDrawable(animation);
animation start;
但是,在不预加载的情况下根据需要加载单个动画会造成轻微延迟。有没有一种方法可以预加载它们(如果有意义的话)或者在代码中如何实现它们方面做些别的事情?我目前正在将动画分割成不同的部分,因此唯一改变的帧是对象的实际动画部分

除此之外,我还能如何处理AnimationDrawable和内存?似乎动画对Android来说是如此重要,必须有更好的、专业的方式来处理动画资源,这样它们才不会破坏内存库,并且仍然是流动的。请让我知道我做这件事的方式很愚蠢。我应该使用不同的动画类,或者根据计时器手动将更改的动画视图指定给动画视图,以便一次加载一个动画视图


我想这是一个混乱的问题——似乎必须有一个标准的方法来处理这类问题。少帧?不同格式的图像?(jpg和png是一样的)

您可以做几件事来最小化内存消耗

  • 将图像大小重新调整为精确的按钮大小。你不需要更大的形象
  • 根据屏幕分辨率调整图像大小。如果你的屏幕很小,他们的 没有理由加载更大的图像
  • 按照android设计指南提供不同分辨率的图像
  • 保留大部分图像修复,仅加载/更改动画部分
防撞

  • 在将映像加载到内存之前,请检查堆内存的总大小
  • 确保垃圾收集工作正常。位图垃圾收集与常规垃圾收集差别不大,取决于Android版本
  • 试试Java引用
您可以做几件事来最小化内存消耗

  • 将图像大小重新调整为精确的按钮大小。你不需要更大的形象
  • 根据屏幕分辨率调整图像大小。如果你的屏幕很小,他们的 没有理由加载更大的图像
  • 按照android设计指南提供不同分辨率的图像
  • 保留大部分图像修复,仅加载/更改动画部分
防撞

  • 在将映像加载到内存之前,请检查堆内存的总大小
  • 确保垃圾收集工作正常。位图垃圾收集与常规垃圾收集差别不大,取决于Android版本
  • 试试Java引用
您可以使用DiskLruCache缓存位图。它可以帮助您解决内存问题,并以相同的质量显示图像。提及

您只需执行一次缓存。之后,它将从缓存文件夹加载图像

     int count = 0;
         Runnable runnable = new Runnable() {

            @Override
            public void run() {
                count++;
                if (count < TOTAL_IMAGES) {
                   loadBitmap(count);
                   handler.postDelayed(runnable, 0);
            }
        }
    };
    handler.postDelayed(runnable, 0);


  // method for loading bitmap from cache folder
  private void loadBitmap(int id) {
            String filePath = Environment.getExternalStorageDirectory()+ "Folder Name/ Image Name " + id ;
            BitmapFactory.Options options = new BitmapFactory.Options();

            Bitmap b = BitmapFactory.decodeFile(filePath, options);
            if (b != null) {
                img.setImageBitmap(b);
                }
        }
int count=0;
Runnable Runnable=新的Runnable(){
@凌驾
公开募捐{
计数++;
如果(计数<图像总数){
加载位图(计数);
handler.postDelayed(可运行,0);
}
}
};
handler.postDelayed(可运行,0);
//从缓存文件夹加载位图的方法
私有void加载位图(int-id){
字符串filePath=Environment.getExternalStorageDirectory()+“文件夹名/图像名”+id;
BitmapFactory.Options=new-BitmapFactory.Options();
位图b=BitmapFactory.decodeFile(文件路径,选项);
如果(b!=null){
img.setImageBitmap(b);
}
}

您可以使用DiskLruCache缓存位图。它可以帮助您解决内存问题,并以相同的质量显示图像。提及

您只需执行一次缓存。之后,它将从缓存文件夹加载图像

     int count = 0;
         Runnable runnable = new Runnable() {

            @Override
            public void run() {
                count++;
                if (count < TOTAL_IMAGES) {
                   loadBitmap(count);
                   handler.postDelayed(runnable, 0);
            }
        }
    };
    handler.postDelayed(runnable, 0);


  // method for loading bitmap from cache folder
  private void loadBitmap(int id) {
            String filePath = Environment.getExternalStorageDirectory()+ "Folder Name/ Image Name " + id ;
            BitmapFactory.Options options = new BitmapFactory.Options();

            Bitmap b = BitmapFactory.decodeFile(filePath, options);
            if (b != null) {
                img.setImageBitmap(b);
                }
        }
int count=0;
Runnable Runnable=新的Runnable(){
@凌驾
公开募捐{
计数++;
如果(计数<图像总数){
加载位图(计数);
handler.postDelayed(可运行,0);
}
}
};
handler.postDelayed(可运行,0);
//从缓存文件夹加载位图的方法
私有void加载位图(int-id){
字符串filePath=Environment.getExternalStorageDirectory()+“文件夹名/图像名”+id;
BitmapFactory.Options=new-BitmapFactory.Options();
位图b=BitmapFactory.decodeFile(文件路径,选项);
如果(b!=null){
img.setImageBitmap(b);
}
}

感谢您的回复。关于提供精确的资源,我之所以要调整所有内容的大小,是因为我有一个按钮布局,这些按钮被设计为拼接在一起以重建一幅图像。整个过程必须与特定的屏幕宽度完全相同,因此为每个屏幕提供精确大小的按钮是不可行的。所有图像加动画的总容量约为2mb。如果我为不同的解决方案提供不同的资源