不明白为什么 outOfMemory on setImageDrawable
Don't understand why OutOfMemory on setImageDrawable
我制作的自定义按钮控件有问题。
该按钮在布局中定义如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_centerInParent="true"
android:layout_margin="20dp"
android:background="#fff"
android:contentDescription="@string/my_button_info"
android:src="@drawable/button_appearance" />
</merge>
和button_appearance是这样定义的:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_pic_down"
android:state_pressed="true" />
<item android:drawable="@drawable/button_pic"
android:state_focused="true" />
<item android:drawable="@drawable/button_pic" />
</selector>
现在,当我按下我的按钮(单击 LinearLayout)时,我将它显示为不同的位图并将其设置为旋转动画,这是动画:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1666"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="359" />
我这样称呼它:
public void animateButton() {
myButton.setEnabled(false);
myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_pic_spin));
myButton.startAnimation(AnimationUtils.loadAnimation(context, R.anim.spinner_animation));
}
然后,当它开始的动作完成时,我停止它:
public void stopAndEnableButton() {
myButton.setEnabled(true);
myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_appearance));
ttcButton.clearAnimation();
}
我在调用 setImageDrawable 的正上方的行中收到了 Crashlytics 的一些崩溃。 Crashlytics 说:
Failed to allocate a 2869648 byte allocation with 1275632 free bytes and 1245KB until OOM
奇怪的是,这里的 png 文件大小都在 25K 左右——而且只有 3 个(button_appearance.xml 中引用了 2 个,button_pic_spin 中引用了普通的 png)我们如何得到当我尝试交换最多应该只有 50K 的东西时需要 2 兆字节?
问题是应该先调用ClearAnimation再调用setImageDrawable吗?系统实际上是在尝试为部分旋转的位图进行大量分配吗?
您的图片太大,请尝试减小尺寸,或尝试使用第二个 post here 中的提示加载它。 (我说的是那些按钮图片)
如果您迫切需要解决方案,请在您的应用程序清单中提供 "largeHeap":true。
Android中图像的内存分配取决于图像的像素宽度和高度。不是磁盘大小。
Image Memory Size = width * height * 4 bytes (byte for red, byte for
green, byte for blue and byte for alpha)
此错误由 Java 虚拟机 (JVM) 在由于内存不足 space 而无法分配对象时引发,而且垃圾收集器无法释放一些 space.
参考:
在清单文件中添加以下实体:android:hardwareAccelerated="false"
,android:largeHeap="true"
:
<application
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">
我制作的自定义按钮控件有问题。 该按钮在布局中定义如下:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:layout_width="180dp"
android:layout_height="180dp"
android:layout_centerInParent="true"
android:layout_margin="20dp"
android:background="#fff"
android:contentDescription="@string/my_button_info"
android:src="@drawable/button_appearance" />
</merge>
和button_appearance是这样定义的:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_pic_down"
android:state_pressed="true" />
<item android:drawable="@drawable/button_pic"
android:state_focused="true" />
<item android:drawable="@drawable/button_pic" />
</selector>
现在,当我按下我的按钮(单击 LinearLayout)时,我将它显示为不同的位图并将其设置为旋转动画,这是动画:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1666"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="359" />
我这样称呼它:
public void animateButton() {
myButton.setEnabled(false);
myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_pic_spin));
myButton.startAnimation(AnimationUtils.loadAnimation(context, R.anim.spinner_animation));
}
然后,当它开始的动作完成时,我停止它:
public void stopAndEnableButton() {
myButton.setEnabled(true);
myButton.setImageDrawable(getContext().getResources().getDrawable(R.drawable.button_appearance));
ttcButton.clearAnimation();
}
我在调用 setImageDrawable 的正上方的行中收到了 Crashlytics 的一些崩溃。 Crashlytics 说:
Failed to allocate a 2869648 byte allocation with 1275632 free bytes and 1245KB until OOM
奇怪的是,这里的 png 文件大小都在 25K 左右——而且只有 3 个(button_appearance.xml 中引用了 2 个,button_pic_spin 中引用了普通的 png)我们如何得到当我尝试交换最多应该只有 50K 的东西时需要 2 兆字节?
问题是应该先调用ClearAnimation再调用setImageDrawable吗?系统实际上是在尝试为部分旋转的位图进行大量分配吗?
您的图片太大,请尝试减小尺寸,或尝试使用第二个 post here 中的提示加载它。 (我说的是那些按钮图片)
如果您迫切需要解决方案,请在您的应用程序清单中提供 "largeHeap":true。
Android中图像的内存分配取决于图像的像素宽度和高度。不是磁盘大小。
Image Memory Size = width * height * 4 bytes (byte for red, byte for green, byte for blue and byte for alpha)
此错误由 Java 虚拟机 (JVM) 在由于内存不足 space 而无法分配对象时引发,而且垃圾收集器无法释放一些 space.
参考:
在清单文件中添加以下实体:android:hardwareAccelerated="false"
,android:largeHeap="true"
:
<application
android:allowBackup="true"
android:hardwareAccelerated="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="@style/AppTheme">