图像连续淡入淡出和内存不足
Continuous crossfade of images and out of memory
我有一个 activity 可以在淡入淡出中显示一些全屏图像。一共有6张图片。为此,我同时使用了 2 个 ImageView 和 2 个动画播放,一个淡出第一个图像,一个淡出第二个图像。我用这个视频作为参考https://www.youtube.com/watch?v=9XbKMUtVnJA
因为我需要它连续 运行,所以我使用计时器每 4 秒安排一次动画。一切正常,但它使用大量内存。要加载我尝试过的图像:
- 视频中使用的基本不推荐方式,即将所有图像加载到可绘制数组中
- 使用 imageview.setImageResource
设置图像
- 使用 Picasso 从资产中加载图像
所有这些方法都是内存密集型的,会导致旧设备(如 Galaxy S2)出现内存不足异常。 Picasso 方法无法正常工作。
我确定有更好的方法,但我不知道,有什么建议吗?
相关代码如下:
private void animateImageview(){
prevImageView.animate().alpha(0);
nextImageView.animate().alpha(1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentDrawable =
(mCurrentDrawable + 1) % imagesToShow.length;
int nextDrawableIndex =
(mCurrentDrawable + 1) % imagesToShow.length;
prevImageView.setImageResource(imagesToShow[mCurrentDrawable]);
nextImageView.setImageResource(imagesToShow[nextDrawableIndex]);
nextImageView.setAlpha(0f);
prevImageView.setAlpha(1f);
}
});
protected void onCreate(Bundle savedInstanceState) {
...
prevImageView.setImageResource(imagesToShow[0]);
nextImageView.setImageResource(imagesToShow[1]);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
animateImageview();
}
}, 5000, 4000);
}
编辑:
清单中的 largeHeap 选项似乎可以解决问题,但我不相信我做这件事是对的。
编辑2:
我使用的解决方案的要点 https://gist.github.com/alexmazza/003e3449c02fe58848a9
请从清单中删除 largeHeap
选项。它不是在解决问题,而是在掩盖问题。
这就是问题
The images are 1536x2048 loaded in an imageview
您不应该只尝试以最大分辨率加载图像,因为正如您所说,例如在 S2 中,其显示为 800 x 480,这有什么意义?
一般来说,您应该做的是将位图加载到您需要的大小的内存中(在您的情况下,它应该与 ImageView 一样大)。您可以在 the official docs.
中按照非常好的教程进行操作
To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it, unless you absolutely trust the source to provide you with predictably sized image data that comfortably fits within the available memory.
[....]
For example, it’s not worth loading a 1024x768 pixel image into memory if it will eventually be displayed in a 128x96 pixel thumbnail in an ImageView.
希望这对您有所帮助。
我有一个 activity 可以在淡入淡出中显示一些全屏图像。一共有6张图片。为此,我同时使用了 2 个 ImageView 和 2 个动画播放,一个淡出第一个图像,一个淡出第二个图像。我用这个视频作为参考https://www.youtube.com/watch?v=9XbKMUtVnJA
因为我需要它连续 运行,所以我使用计时器每 4 秒安排一次动画。一切正常,但它使用大量内存。要加载我尝试过的图像:
- 视频中使用的基本不推荐方式,即将所有图像加载到可绘制数组中
- 使用 imageview.setImageResource 设置图像
- 使用 Picasso 从资产中加载图像
所有这些方法都是内存密集型的,会导致旧设备(如 Galaxy S2)出现内存不足异常。 Picasso 方法无法正常工作。
我确定有更好的方法,但我不知道,有什么建议吗?
相关代码如下:
private void animateImageview(){
prevImageView.animate().alpha(0);
nextImageView.animate().alpha(1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mCurrentDrawable =
(mCurrentDrawable + 1) % imagesToShow.length;
int nextDrawableIndex =
(mCurrentDrawable + 1) % imagesToShow.length;
prevImageView.setImageResource(imagesToShow[mCurrentDrawable]);
nextImageView.setImageResource(imagesToShow[nextDrawableIndex]);
nextImageView.setAlpha(0f);
prevImageView.setAlpha(1f);
}
});
protected void onCreate(Bundle savedInstanceState) {
...
prevImageView.setImageResource(imagesToShow[0]);
nextImageView.setImageResource(imagesToShow[1]);
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
animateImageview();
}
}, 5000, 4000);
}
编辑: 清单中的 largeHeap 选项似乎可以解决问题,但我不相信我做这件事是对的。
编辑2: 我使用的解决方案的要点 https://gist.github.com/alexmazza/003e3449c02fe58848a9
请从清单中删除 largeHeap
选项。它不是在解决问题,而是在掩盖问题。
这就是问题
The images are 1536x2048 loaded in an imageview
您不应该只尝试以最大分辨率加载图像,因为正如您所说,例如在 S2 中,其显示为 800 x 480,这有什么意义?
一般来说,您应该做的是将位图加载到您需要的大小的内存中(在您的情况下,它应该与 ImageView 一样大)。您可以在 the official docs.
中按照非常好的教程进行操作To avoid java.lang.OutOfMemory exceptions, check the dimensions of a bitmap before decoding it, unless you absolutely trust the source to provide you with predictably sized image data that comfortably fits within the available memory.
[....]
For example, it’s not worth loading a 1024x768 pixel image into memory if it will eventually be displayed in a 128x96 pixel thumbnail in an ImageView.
希望这对您有所帮助。