Java 在android中加载图像会分配大量内存
我正在使用720X1136大小的图像作为我的应用程序的启动屏幕,该应用程序仅针对三星Galaxy Nexus手机。实际文件大小为513Kb(从浏览器中找到)。当活动调用onCreate方法并设置内容视图时,日志会提到内存分配为13.5 MB 这是我正在加载的活动,背景中有一个图像Java 在android中加载图像会分配大量内存,java,android,memory-management,android-memory,Java,Android,Memory Management,Android Memory,我正在使用720X1136大小的图像作为我的应用程序的启动屏幕,该应用程序仅针对三星Galaxy Nexus手机。实际文件大小为513Kb(从浏览器中找到)。当活动调用onCreate方法并设置内容视图时,日志会提到内存分配为13.5 MB 这是我正在加载的活动,背景中有一个图像 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width=
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ImageView android:src="@drawable/splashscreen"
android:id="@+id/splashscreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:visibility="invisible"
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>
如何减少内存分配
谢谢13mb很好,在允许范围内。每当启动屏幕消失时,位图将被回收,内存将重新用于应用程序的其余部分 您可以使用以下技巧来尽量减少此内存足迹: 。使用9面片拉伸图像的边框(如果设计允许) 。降低图像质量(看起来很糟糕) 使用@drawable/splashscreen将此图像作为9-Patch图像 这样可以减少内存分配
没有人需要像素完美的启动屏幕,您可以轻松地将图像大小减少到原来的一半,这将为您节省3/4的内存占用
另一方面,我建议大家不要使用闪屏,这里有一篇关于这个话题的好文章:,否则你可能会在谷歌上搜索“闪屏是邪恶的”,并得到更多反对使用闪屏的理由。以下是解决问题的步骤
mRelativeLayout=(RelativeLayout)findViewById(R.id.relative_view);
intializeScreenSize();
mBitmap=decodeSampledBitmapFromResource(getResources(),R.drawable.splash_background,width,height);
mDrawable=new BitmapDrawable(getResources(), mBitmap);
mRelativeLayout.setBackgroundDrawable(mDrawable);
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 void intializeScreenSize(){
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
height= displaymetrics.heightPixels;
width= displaymetrics.widthPixels;
}
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) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
}
return inSampleSize;
}
下面是一些与android中加载位图相关的链接。
正如
亚历克斯·奥尔洛夫(Alex Orlov)
所说:“磁盘上的大小与内存中位图的大小无关。在第一种情况下,图像被压缩,而位图则只是一组原始像素。”然而,即使考虑到它被存储为原始图像,20MB仍然太多。如果我们认为<4b>强>每个像素,那就是<>强> 5Mpx图像,但是你所发布的图片肯定要小一些。
我也遇到了类似的问题:我加载了一个原始格式为8MB的图像,但分配了32MB。后来我发现这是由dpi缩放造成的。如果您的图像位于“drawable”文件夹中,它将根据当前屏幕dpi自动缩放。我有一个XHDPI屏幕,所以我的图像水平缩放了2倍,垂直缩放了2倍,这就是为什么它占用了4倍的内存
您可以在此处找到有关dpi工作原理的更多信息:
如果您不想自己使用android的自动功能和缩放图像,只需将“drawable”文件夹重命名为“drawable nodpi”。“drawable”文件夹中标记为“nodpi”的所有图像将按原样加载。在relativelayout中将其用作背景可能会为您节省一些内存…您可以在使用后尝试完成启动屏幕活动。您需要按代码将图像设置为根布局,就像我在android中给出的那样。我尝试按代码设置1 Mb图像,并直接在布局中按设置,并找到按设置的第一个图像应用程序输入和输出内存的布局崩溃。