内存问题绘制5个小图像

时间:2017-02-28 21:39:23

标签: android

我的应用程序使用太多内存,我不太清楚为什么。我正在制作单人纸牌游戏。我使用了10个相等宽度RelativeLayouts的链式ConstraintLayout(每个堆栈卡为1)。 [我知道我可以使用其他Viewgroups]。

我的应用程序正在使用~15mb内存,直到我这样做;

public void DrawCardsMat0()
{
    RelativeLayout mat = (RelativeLayout) findViewById(R.id.PLAY_Mat0);
    mat.removeAllViews();
    RelativeLayout rl = new RelativeLayout(this);

    for (PlayingCard playingCard : Stack0.Cards)
    {
        ImageView myImg = GetCardImage(playingCard);
        RelativeLayout.LayoutParams lay = new RelativeLayout.LayoutParams(CardWidth, CardHeight);
        lay.setMargins(0, playingCard.UI_MarginTop, 0, 0);
        mat.addView(myImg, lay);
    }
}

public ImageView GetCardImage(PlayingCard playingCard)
{
    ImageView myImg = new ImageView(this);
    // a simple switch is used to here to pick the drawable. Removed as there's 52 cards)
    myImg.setImageResource(R.drawable.s1); 
    return myImg;
}

CardWidth和CardHeight是整数(150和210,粗略。像素)。

这会绘制五张牌,每张.jpg约为60KB(是的,KB)。这导致60MB的内存使用量。 10 cols == 600mb的内存(我假设,之前是它的OOM)。

图像位于RelativeLayout中,并且彼此叠加。 MarginTop用于"堆栈"他们。

提前致谢

---更新1 ---

我现在正在使用46KB的bmp图像。 在XML中创建5个ImageView(一个堆栈值得)(并且不要在代码中调用任何东西)使用~50mb内存。使用LinearLayout测试。 在代码中创建相同的图像使用相同的内存量。

---更新2 --- 如果我创建一个新的Activity,只有一个简单的LinearLayout和5个ImageViews,而且没有java代码,它仍然使用~50MB内存。

1 个答案:

答案 0 :(得分:1)

使用位图时,应始终小心。我将描述最重要的几点并考虑它们,你可以改变卡片图像的工作方式。

  1. 内存中的位图始终以非压缩格式存在,因此其大小将与.jpg / .png / .webp / .[whatever compressed format]的大小不同。实际大小取决于Bitmap.Config,但默认情况下,Android将使用ARGB_8888(Alpha通道为1个字节,R / G / B通道为1个字节)。您可以通过以.bmp格式保存图像来粗略估计内存中的大小。
  2. 当您将<bitmap>标记用于drawable时,表示在运行时位图将包含在BitmapDrawable中。如您所见,默认情况下,位图将按原样加载,采用原始大小。
  3. 当您致电myImg.setImageResource(R.drawable.s1)时,意味着位图将具有与之前相同的内存,它将根据{{1}的大小使用矩阵进行缩放你指定的{和ImageView
  4. 考虑到这一点,您可能希望将缩减的位图加载到内存中,具体取决于视图大小。您可以使用scaleType类来代替。我建议您阅读这两篇文章,以了解Android如何使用位图:Managing Bitmap MemoryLoading Large Bitmaps Efficiently
  5. 您也可以考虑使用某些图像库,例如PicassoGlide,它们可以根据BitmapFactory的大小加载缩小尺寸的位图。您还可以尝试使用Fresco将位图保留在ImageView堆之外。
  6. 如果您有这种可能性,最好还是以JVM格式存放卡片。然后你可以使用向量而不是位图,这对内存更友好(因为SVG只是一组关于如何绘制的指令)。但是,如果文件非常复杂SVG,您可能会遇到另一个问题 - 绘制它需要花费大量时间。查看this有关如何将其与SVG一起使用的文章。