Android 绘制5个小图像时内存问题

Android 绘制5个小图像时内存问题,android,Android,我的应用程序占用了太多的内存,我不太清楚为什么。我在玩纸牌游戏。我使用的是10个等宽相对长度的链式ConstraintLayout(每叠卡1个)。[我知道我可以使用其他视图组] 我的应用程序正在使用~15mb内存,直到我这样做 public void DrawCardsMat0() { RelativeLayout mat = (RelativeLayout) findViewById(R.id.PLAY_Mat0); mat.removeAllViews(); Rela

我的应用程序占用了太多的内存,我不太清楚为什么。我在玩纸牌游戏。我使用的是10个等宽相对长度的链式ConstraintLayout(每叠卡1个)。[我知道我可以使用其他视图组]

我的应用程序正在使用~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);
    }
}

CardWidth和CardHeight是整数(150和210,大致为.Pixels)

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

这些图像位于相对位置,并且相互重叠。MarginTop用于“堆叠”它们

提前谢谢

---更新1---

我现在使用的是46KB的bmp图像。 在XML中创建5个ImageView(一个堆栈的价值)(并且不在代码中调用任何内容)使用~50mb内存。使用线性布局进行测试。 在代码中创建相同的图像使用相同的内存量

---更新2---
如果我创建一个新的活动,只使用一个简单的LinearLayout和5个ImageView,而不使用java代码,它仍然使用~50MB内存

使用位图时,应始终小心。我将描述最重要的几点,考虑到它们,您可以改变处理卡片图像的组织方式

  • 内存中的位图始终以未压缩格式存在,因此其大小将不同于您的
    .jpg
    /
    .png
    /
    .webp
    /
    [任何压缩格式]
    。实际大小取决于,但默认情况下Android将使用
    ARGB_8888
    (1字节用于alpha通道,1字节用于每个R/G/B通道)。通过以
    .bmp
    格式保存图像,可以粗略估计内存中的大小
  • 当您将
    标记与drawable一起使用时,这意味着运行时位图将被包装在中。如您所见,默认情况下,位图将按原样加载,采用原始大小
  • 当您调用
    myImg.setImageResource(R.drawable.s1)
    时,这意味着位图在内存中的大小将与以前的大小相同,它将根据您指定的
    ImageView
    scaleType
    的大小使用矩阵进行缩放
  • 考虑到这一点,您可能希望根据视图大小将缩小的位图加载到内存中。您可以使用
    BitmapFactory
    类来实现这一点。我建议您阅读这两篇文章,以了解Android是如何使用位图的:和
  • <> LI>您也可以考虑使用一些图像库,例如,或者可以根据代码大小> IVIEVIEW 加载缩进位图。您还可以尝试使用它将位图保持在
    JVM
    堆之外
  • 如果您有这种可能性,最好使用
    SVG
    格式的卡。然后,您可以使用向量而不是位图,这对内存更友好(因为
    SVG
    只是一组关于如何绘制的说明)。然而,如果是真正复杂的
    SVG
    文件,您可能会遇到另一个问题-绘制它需要很多时间。查看有关如何将其与
    ImageView
    一起使用的文章

  • .jpg是压缩,它只存在于文件中,在运行时内存中,每个图像都是未压缩的格式。要粗略估计内存中的卡大小,您可以尝试将其另存为.bmpInteresting,谢谢。将一幅图像保存为bmp,大约为1mb。我已经调整了一幅图像的大小(更小),并将其保存为bmp。是124KB。然后将该图像用于所有5张卡。内存已从~60MB降至~40MB。相对而言,尝试使用它需要花费大量的成本frameLayout@JCDecary
    RelativeLayout
    仅在布局/测量时间方面成本高昂(只有在布局复杂的情况下才会有这种感觉),考虑到内存消耗没有什么可怕的。谢谢。我会消化和阅读,然后再给你回复。再次感谢!
    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;
    }