<ImageView
android:id="@+id/bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="@drawable/bg" />
@ drawable / bg 1600 * 1800(W * H)
我尝试使用
BitmapFactory.decodeResource(getResources(), R.drawable.bg, options);
使用inSampleSize
以下是日志:
02-05 05:32:05.841: E/screenWidth in px =(876): 768
02-05 05:32:05.841: E/screenheight in px =(876): 1184
02-05 05:32:05.841: E/screenDensity =(876): 2.0
02-05 05:32:05.841: E/screenDensityDpi =(876): 320
02-05 05:32:05.841: E/decodeSampledBitmapFromResource reqWidth =(876): 768
02-05 05:32:05.851: E/decodeSampledBitmapFromResource reqHeight =(876): 1184
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageHeight =(876): 1800
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageWidth =(876): 1600
02-05 05:32:05.921: E/decodeSampledBitmapFromResource imageType =(876): image/jpeg
02-05 05:32:05.951: E/calculateInSampleSize: inSampleSize =(876): 1
02-05 05:32:09.291: E/dalvikvm-heap(876): Out of memory on a 44441616-byte allocation.
02-05 05:32:09.391: E/AndroidRuntime(876): FATAL EXCEPTION: main
02-05 05:32:09.391: E/AndroidRuntime(876): Process: com.example.splash, PID: 876
02-05 05:32:09.391: E/AndroidRuntime(876): java.lang.OutOfMemoryError
02-05 05:32:09.391: E/AndroidRuntime(876): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:587)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:422)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:445)
02-05 05:32:09.391: E/AndroidRuntime(876): at com.example.splash.SecondActivity.decodeSampledBitmapFromResource(SecondActivity.java:103)
02-05 05:32:09.391: E/AndroidRuntime(876): at com.example.splash.SecondActivity.onCreate(SecondActivity.java:57)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.Activity.performCreate(Activity.java:5231)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.os.Handler.dispatchMessage(Handler.java:102)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.os.Looper.loop(Looper.java:136)
02-05 05:32:09.391: E/AndroidRuntime(876): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-05 05:32:09.391: E/AndroidRuntime(876): at java.lang.reflect.Method.invokeNative(Native Method)
02-05 05:32:09.391: E/AndroidRuntime(876): at java.lang.reflect.Method.invoke(Method.java:515)
02-05 05:32:09.391: E/AndroidRuntime(876): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-05 05:32:09.391: E/AndroidRuntime(876): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-05 05:32:09.391: E/AndroidRuntime(876): at dalvik.system.NativeStart.main(Native Method)
对于高度 1184
的设备inSampleSize将为1(因此无变化)
所以,在所有这个过程中都会发生无用的事情,并且会出现相同的 OOM 。
这个单一的屏幕显示我需要使用 44 mb的内存:
long totalMem = Runtime.getRuntime().totalMemory();
如果我将image src设置为@null,则上述值为3 mb
这是一种可靠的方法来查找应用程序的内存使用情况吗?
请帮助我如何在没有任何OOM的情况下加载如此高分辨率的图像。
答案 0 :(得分:3)
Picasso.with(context).load(R.drawable.bg).into(iv);
使用picasso图像加载器,因为它非常有效link
答案 1 :(得分:3)
Picasso和Universal-image-loader是我用来加载大图像的库。
毕加索:http://square.github.io/picasso/Universal-image-loader:https://github.com/nostra13/Android-Universal-Image-Loader
同样在你的Manifest中放置android:largeHeap =“true”将为重载进程提供额外的内存。
答案 2 :(得分:0)
我曾经遇到过同样的问题,但这很容易出错。
如果你的背景在drawable文件夹中,这将对你有帮助。
因为如果你将你的背景放在drawable
文件夹中,它将自动按比例缩放到你的xhdpi屏幕,所以它会尝试加载3200 * 3600的图像,这会给你OutOfMemory错误。您需要将图片放入drawable-nodpi
或drawable-xxhdpi
。我建议使用第二个,因为您的图像将按比例缩小以获得低分辨率屏幕(通常也有较低的内存可用)。
答案 3 :(得分:0)
我遇到了这个问题 - 我最终降低了图像的质量:
public NSData fixSize(UIImage file)
{
if (file.Size.Width > 400 || file.Size.Height > 400)
{
// Figure out the ratio
double ratioX = (double)400 / (double)file.Size.Width;
double ratioY = (double)400 / (double)file.Size.Height;
// use whichever multiplier is smaller
double ratio = ratioX < ratioY ? ratioX : ratioY;
// now we can get the new height and width
int newHeight = Convert.ToInt32(file.Size.Height * ratio);
int newWidth = Convert.ToInt32(file.Size.Width * ratio);
Console.WriteLine("rescaling image to y:" + newHeight.ToString() + " and x:" + newWidth.ToString());
file = file.Scale(new Size((int)newWidth, (int)newHeight));
}
if (file == null) return null;
Console.WriteLine("setting image data to quality " + quality.ToString());
NSData data = file.AsJPEG(quality);
if (data.Length > 400000)
{
quality -= 0.1f;
if (quality - 0.1f < 0.1f)
{
}
Console.WriteLine("image data still too large will try at " + quality.ToString());
fixSize(file);
}
return data;
}
正如您所看到的那样,它会逐渐降低图像质量,直到它变得易于管理。
答案 4 :(得分:-1)
有一些关于
的教程Where我找到了像
这样的内容为了避免java.lang.OutOfMemory异常,请在解码之前检查位图的尺寸,除非您完全信任该源为您提供可预测大小的图像数据,这些数据可以轻松地放入可用内存中。
我建议使用 AQuery (android-query)
//fetch and set the image from internet, cache with file and memory
aq.id(R.id.image1).image("http://www.vikispot.com/z/images/vikispot/android-w.png");
//returns the cached file by url, returns null if url is not cached
File file = aq.getCachedFile(url);