我正在应用程序中的 4 个不同位置设置帮助屏幕图像。 Activity 代码如下-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.help_list);
int screenType = getIntent().getIntExtra("screenName", 0);
ImageView imageView = (ImageView) findViewById(R.id.help_image);
switch (screenType) {
case 1:
imageView.setImageResource(R.drawable.help0);
break;
case 2:
imageView.setImageResource(R.drawable.help1);
break;
case 3:
imageView.setImageResource(R.drawable.help2);
break;
case 4:
imageView.setImageResource(R.drawable.help3);
break;
}
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
此代码在大多数设备上成功执行,但在某些设备(例如三星)上,应用程序崩溃并出现内存不足异常。
我尝试回收位图-
BitmapDrawable bitmapDrawable = ((BitmapDrawable) imageView.getDrawable());
if (bitmapDrawable != null) {
bitmapDrawable.getBitmap().recycle();
}
但是上面的代码总是在bitmapDrawable
的值中给出null。如何修复此内存不足异常?
附注图像可绘制的最大大小为 80kb
最佳答案
图像的像素大小是多少?由于图像存储在java堆中,因此它们没有被压缩。这意味着位图的每个像素在堆中最多可以占用 32 位 = 4 个字节。 因此,对于尺寸为 1920 x 1080 的图像(也许您还针对大分辨率平板电脑),即:
1920 x 1080 x 4 bytes = 8294400 bytes, 8.29 megabytes.
现在这在平板电脑上可能没问题,但在可能有 64 MB 堆空间的旧手机上,您可能很容易遇到 OutOfMemoryExceptions。
那么你能做什么呢?
如果您仅针对手机,您可以将图像调整为较小的尺寸吗?这主要基于反复试验,也取决于图像的使用(模糊的背景图像 VS 具有重要细节的 map 图像)。
使用不同的位图配置。默认为 RGB_8888,即每个 channel 8 位 (ARGB) = 32 位。如果您不需要 Alpha channel (透明度),并且图像不必具有超高品质,您应该尝试一下
RGB_565
。它的质量下降非常小,但几乎无法察觉。作为返回,它消耗的内存减半(5 + 6 + 5 = 每像素 16 位)。最重要的修复:您可以为不同的屏幕密度提供不同的图像。这是一个例子。假设我们要使用计算中的全高清图片。 对于较小的屏幕,我们将其缩小,以节省内存。有一些工具可以根据不同的密度缩小图像,请参阅this question 。 按照密度准则,您可以将以下具有尺寸的图像放入给定目录中:
- 可绘制-xxhdpi:1920x1080
- 可绘制xhdpi:1280x720
- drawable-hdpi:960x540
- 可绘制 mdpi:640x360
因此,虽然该图像在大型平板电脑上会占用 8.29 Mb 堆空间,但在旧手机上只会占用 921 Kb,这正是我们想要的。 不过,它确实会增加 APK 大小,因为现在它包含 4 个图像,而不是一个。
关于android - 在 ImageView 中设置图像时内存不足,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33279223/