2

我正在使用尺寸为 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>

如何减少这种内存分配?

谢谢

4

5 回答 5

2

使用 @drawable/splashscreen 这个图像作为 9-Patch 图像,然后它会减少内存分配

于 2012-11-09T10:44:41.697 回答
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中加载位图相关的链接。 SO答案 有效地加载位图

于 2012-11-09T11:15:18.087 回答
0

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

我有类似的问题:我正在加载一个具有 8MB 原始格式的图像,但是,为它分配了 32MB。后来我发现这是由 dpi 缩放引起的。如果您的图像在“drawable”文件夹中,它将根据当前屏幕 dpi 自动缩放。我有一个 XHDPI 屏幕,所以我的图像水平缩放 2 倍,垂直缩放 2 倍,这就是它占用 4 倍更多内存的原因。

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

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

于 2012-11-09T11:21:09.570 回答
0

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

另一方面,我建议完全避免启动画面,这里有一篇关于这个主题的好文章:“启动画面是邪恶的,不要使用它们!” ,否则你可能会在谷歌上搜索“启动画面是邪恶的”并获得更多反对使用它们的论据。

于 2012-11-09T11:14:17.463 回答
0

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

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

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

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

于 2012-11-09T10:44:02.463 回答