在android中加载图像会分配一个大内存

时间:2012-11-09 10:34:43

标签: 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="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>

如何减少内存分配?

由于

5 个答案:

答案 0 :(得分:2)

  

使用@ drawable / splashscreen此图像作为9-Patch图像   那么它会减少内存分配

答案 1 :(得分:1)

以下是解决问题的步骤。

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中的Load Bitmap相关的一些链接。 SO Answer Load Bitmap Efficiently

答案 2 :(得分:0)

13mb很好并且在限制范围内。每当此启动画面消失时,位图将被回收,内存将重新用于应用程序的其余部分。

可以用来尝试最小化此内存占用的技巧是:

。使用9补丁来拉伸图像的边框(如果设计允许)

。降低图像质量(看起来很糟糕)

答案 3 :(得分:0)

没有人需要像素完美的闪屏,你可以轻松地将图像尺寸缩小到原来的一半,这样可以节省3/4的内存占用量。

在另一个说明中,我建议完全避免使用启动画面,这里有一个关于这个主题的好文章:"Splash screens are evil, don’t use them!",否则你可能会搜索谷歌“启动屏幕是邪恶的”并获得更多反对使用的论据它们。

答案 4 :(得分:0)

正如Alex Orlov所述:“磁盘上的大小与内存中位图的大小无关。在第一种情况下,图像被压缩,而位图,另一方面,只是原始的一组像素。”然而,即使考虑将其存储为原始图像, 20MB 仍然太过分了。如果我们考虑每像素 4B ,那将是 5Mpix 图片,但您发布的图片肯定会更小。

我有类似的问题:我正在加载原始格式为8MB的图片,但是为此分配了32MB。我后来发现这是由dpi缩放引起的。如果您的图像位于“可绘制”文件夹中,它将根据当前屏幕dpi自动缩放。我有一个XHDPI屏幕,因此我的图像水平缩放2倍,垂直缩放2倍,这就是为什么它需要4倍的内存。

您可以在此处找到有关dpi如何工作的更多信息:http://developer.android.com/guide/practices/screens_support.html

如果您不想使用此自动Android功能并自行缩放图像,只需将“drawable”文件夹重命名为“drawable-nodpi”即可。 “drawable”文件夹中标记为“nodpi”的所有图像都将按原样加载。