如何限制观看次数?

我想弄清楚Android布局和视图的主要有效性问题。 我正在做一个研究,但也许有人已经有答案了。

我有一个RelativeLayoutdynamic填充视图。 基本上,应用程序加载一个论坛线程在XML中,然后呈现讨论树,使每个消息显示在自己的一组视图。 我决定不使用WebView因为我想实现一些客户端function,这些function在自定义视图上应该比在HTML页面上更容易。

但是这种方法存在一个主要缺陷:很重。

第一个问题(我已经解决了)是嵌套的意见 。 这不是问题,我的布局几乎是平坦的,所以最大深度是10-12(从最上面的PhoneWindow $ DecorView算起,实际深度取决于数据)。

现在我已经达到了以某种方式连接到(或由于)视图的资源消耗引起的下一个限制。 加载数据后,应用程序挂起一段时间来构build布局(创build视图并使用数据填充它们),并且挂起时间似乎与数据大小成线性关系; 如果数据足够大,视图将永远不会出现(最终系统build议closures应用程序,因为它没有响应)。

现在的问题是:

  1. 内存消耗是否大大依赖于视图类? 换句话说, ButtonTextViewImageView之间有什么主要区别? 我可以附加一个点击处理程序到任何视图,所以他们没有太多的用法。

  2. 背景图片是否会影响性能? 如果在N视图中设置相同的图像,它会使布局 N倍吗? (我明白,这个问题可能看起来很愚蠢,但无论如何。)

  3. 九块图像比一般的图像重得多吗? 更好的方法是创buildN视图,每个视图都有一些背景图像,或者制作一个宽度为N倍并具有重复背景的视图?

  4. 给定一些布局,首先应该优化哪些内容:总体视图数量,嵌套级别还是别的?

  5. 最有趣的。 是否可以衡量或至less估计活动所消耗的资源及其意见? 如果我做一些改变,我怎么能看到我正确的方向?

UPDATE

感谢User117,我现在回答了一些问题。 我已经使用了层次浏览器,并优化了我的布局:与以前相比,现在整体数量减less了将近两倍,嵌套也减less了。

但是,应用程序仍然挂在一个大的论坛上。

更新2

我将debugging器连接到我的设备,发现应用程序内存不足。

但是我非常意外的是,在填充布局之后发生错误。 顺序如下:

  1. 我所有的意见都添加了。 当他们被添加时,我可以看到一个轻微的减速。
  2. 几乎没有任何事情发生几秒钟。 在这段时间内,日志中会生成一些信息消息,它们是相同的: [global] Loaded time zone names for en_US in XXXXms ,唯一的区别是毫秒数。
  3. 内存不足的错误信息产生: [dalvikvm-heap] Out of memory on a N-byte allocation (实际大小不一)。 长的错误报告开始。

这是什么意思? 看起来渲染有自己的需求,可能是相当可观的。

更新3

最后我发现了核心问题。 这里是我的应用程序的截图,请参阅下面的图像说明。

消息的树状分层结构。

每封邮件都包含一个圆形button,用于显示或隐藏回复以及button右侧的红色内容框。 这非常简单,只需要6个视图,包括布局。

问题是这些连接线的缩进显示哪个消息与哪个连接有关。

在我目前的实现中,缩进是由小的ImageView的,每个都包含一个显示空白空间或垂直线或类似T的连接器或类似L的angular的方形图像。 所有这些视图在包含整个讨论树的大型RelativeLayout中彼此alignment。

这适用于中小型树(最多可达数百条消息),但是当我尝试加载大型树(2K +消息)时,我得到了上面更新2中所述的结果。

显然,我在这里有两个问题。 我产生了大量的视图都消耗内存,这些视图是ImageView的需要更多的内存来渲染,因为他们呈现一个位图,因此创buildgraphicscaching(根据User117在评论中给出的解释)。

我试图禁用加载图像到缩进视图,但没有效果。 似乎增加了大量的视图足够吃所有可用的内存。

我的另一个想法是为每个消息创build一个包含所有pipe道和angular落的缩进图像,因此每个消息将具有唯一的缩进视图,而不是10或20个。但是,这更加消耗:我内存不足填充布局的中间。 (我在地图中caching了图像,所以没有创build两个具有相同图像序列的位图,这没有帮助。)

所以我得出结论说我已经死了。 是否有可能一次绘制所有这些线?

Solutions Collecting From Web of "如何限制观看次数?"

  1. 不同的View是不同种类的对象 。 有些只draw()轻量级的东西,有些可以容纳大的位图对象,处理器对象等等。 所以,不同的View会消耗不同数量的RAM。

  2. 如果在视图之间共享相同的Bitmap对象,则RAM中只有一个对象,每个视图都将有一个指向该对象的引用variables。 但是,当View被绘制时,并不是这样:在屏幕上的n个位置绘制相同的位图n次会消耗n次CPU,并为每个View生成n个不同的bitmap_cache

  3. 9幅图像的每一边实际上比原始图像大2个像素。 它们与文件没有多大区别。 当他们被吸引时,两者都可以被缩放,并且将占用几乎相等的空间。 唯一的区别是9-Patch的缩放比例是不同的。

    1. 当子视图是透明的,设置较大的父视图的背景会更好,背景将显示。

    2. 您可以保存小图像并设置平铺背景,以便可以填充大面积。

  4. 嵌套是首先要优化的,因为所有的视图都可能在给定的时间不可见,比方说,在滚动布局中只有几个视图是可见的。 那么你可以减less使用的总观看次数。 从ListView获取提示:鉴于用户一次只能看到一组子数据,它会重新循环查看 。 并节省了大量的资源。

  5. SDK为此提供了Hierarchy Viewer工具。 它显示了正在运行的布局的完整树结构,也为布局的缓慢部分放置了红色标记。

一个好的布局是:

  1. 易于测量(避免复杂的加权宽度,高度和路线)。 例如,对于每个孩子而不是为layout_gravity="left" ,parent可以有gravity="left"

  2. 深度较小,每个重叠视图在画面绘制时添加另一个要合成的图层。 每个嵌套的视图结构,要求链接的布局调用。

  3. 是聪明的,重新循环观点,而不是创造所有的人。

  4. 重用它的部分:像<merge><include>这样的标签。

更新: 这个问题的答案,在android中显示树视图的许多方法。