Android ImageSwitcher - 切换图片时OutOfMemory(非常小)
Android ImageSwitcher - OutOfMemory when switching images (very small)
我在 ImageSwitcher 中切换图像时遇到了一些 OutOfMemory 崩溃,这种情况很少见,但有时会发生(对我来说从来没有,否则我可以调试它哈哈)。
我只有 5 张图片 (PNG),每张图片都在 10-60kb 之间,老实说我很惊讶。这是代码:
frameImages = new int[]{R.drawable.f_0, R.drawable.f_1, R.drawable.f_2, R.drawable.f_3, R.drawable.f_4};
...
public void switchImage() {
int frame = getFrame();
int image = frameImages[frame];
// imageSwitcher.startAnimation(getAnimation());
if (frame == 0)
startYAxisRotation(imageSwitcher, 400);
imageSwitcher.setImageResource(image); //CRASHES HERE
}
我是不是做错了什么?
堆栈跟踪:
java.lang.OutOfMemoryError:
at android.graphics.BitmapFactory.nativeDecodeAsset(BitmapFactory.java:0)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
at android.content.res.Resources.loadDrawable(Resources.java:3022)
at android.content.res.Resources.getDrawable(Resources.java:1586)
at android.widget.ImageView.resolveUri(ImageView.java:648)
at android.widget.ImageView.setImageResource(ImageView.java:377)
at android.widget.ImageSwitcher.setImageResource(ImageSwitcher.java:41)
at com.myapp.MainActivity.switchImage(MainActivity.java:143)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Method.java:0)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(NativeStart.java:0)
添加android:largeHeap="true"
在您的清单文件中。
希望能解决您的问题。
不幸的是,如果上述 None 有效,请将其添加到您的清单文件中。内部应用程序标签
<application
android:largeHeap="true"
详情
Strange out of memory issue while loading an image to a Bitmap object
使用以下代码,您可以在将位图加载到 ImageSwitcher 之前降低位图的分辨率。
public void switchImages(){
//Create a Bitmap with the resolution based on the view size.
//getWidth and getHeight will not work until the layout as finished,
//if you need to show an image when the Activity is created you need
//to follow this link:
Bitmap smallBitmap = decodeSampledBitmapFromResource(getResources(), yourDrawableId,
imageSwitcher.getWidth(), imageSwitcher.getHeight())
//use a drawable, because you can create it from a custom Bitmap
BitmapDrawable drawable = new BitmapDrawable(getResources(), smallBitmap);
imageSwitcher.setImageDrawable(drawable);
}
下面这两个方法是从开发者网站上复制过来的here
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
因此,解决方案是降低图像的分辨率(我在 photoshop 中手动调整大小)。从 620x1080 到 800x460,一切正常。
结论:图片大小并不重要,图片分辨率才是。
PS: MatPag 理论上应该也是正确的,它实际上和我做的一样——除了他是用代码做的,我自己在 photoshop 中手动做的。但我认为手动操作更好恕我直言。
我在 ImageSwitcher 中切换图像时遇到了一些 OutOfMemory 崩溃,这种情况很少见,但有时会发生(对我来说从来没有,否则我可以调试它哈哈)。
我只有 5 张图片 (PNG),每张图片都在 10-60kb 之间,老实说我很惊讶。这是代码:
frameImages = new int[]{R.drawable.f_0, R.drawable.f_1, R.drawable.f_2, R.drawable.f_3, R.drawable.f_4};
...
public void switchImage() {
int frame = getFrame();
int image = frameImages[frame];
// imageSwitcher.startAnimation(getAnimation());
if (frame == 0)
startYAxisRotation(imageSwitcher, 400);
imageSwitcher.setImageResource(image); //CRASHES HERE
}
我是不是做错了什么?
堆栈跟踪:
java.lang.OutOfMemoryError:
at android.graphics.BitmapFactory.nativeDecodeAsset(BitmapFactory.java:0)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:677)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:507)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:872)
at android.content.res.Resources.loadDrawable(Resources.java:3022)
at android.content.res.Resources.getDrawable(Resources.java:1586)
at android.widget.ImageView.resolveUri(ImageView.java:648)
at android.widget.ImageView.setImageResource(ImageView.java:377)
at android.widget.ImageSwitcher.setImageResource(ImageSwitcher.java:41)
at com.myapp.MainActivity.switchImage(MainActivity.java:143)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5293)
at java.lang.reflect.Method.invokeNative(Method.java:0)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(NativeStart.java:0)
添加android:largeHeap="true"
在您的清单文件中。
希望能解决您的问题。
不幸的是,如果上述 None 有效,请将其添加到您的清单文件中。内部应用程序标签
<application
android:largeHeap="true"
详情
Strange out of memory issue while loading an image to a Bitmap object
使用以下代码,您可以在将位图加载到 ImageSwitcher 之前降低位图的分辨率。
public void switchImages(){
//Create a Bitmap with the resolution based on the view size.
//getWidth and getHeight will not work until the layout as finished,
//if you need to show an image when the Activity is created you need
//to follow this link:
Bitmap smallBitmap = decodeSampledBitmapFromResource(getResources(), yourDrawableId,
imageSwitcher.getWidth(), imageSwitcher.getHeight())
//use a drawable, because you can create it from a custom Bitmap
BitmapDrawable drawable = new BitmapDrawable(getResources(), smallBitmap);
imageSwitcher.setImageDrawable(drawable);
}
下面这两个方法是从开发者网站上复制过来的here
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
因此,解决方案是降低图像的分辨率(我在 photoshop 中手动调整大小)。从 620x1080 到 800x460,一切正常。
结论:图片大小并不重要,图片分辨率才是。
PS: MatPag 理论上应该也是正确的,它实际上和我做的一样——除了他是用代码做的,我自己在 photoshop 中手动做的。但我认为手动操作更好恕我直言。