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