【发布时间】:2011-06-28 16:36:15
【问题描述】:
在查看我的应用程序中的性能问题时,我发现每次按下按钮都会触发对完整 onMeasure()/layout() 循环的调用。我没有理由尝试重新布置整个应用程序。没有添加或删除任何内容,也没有更改我可以看到的大小。
当布局非常拥挤时,问题往往会发生,并且底部一排按钮可能超出屏幕边缘一两个像素。
有人有这方面的经验吗?有什么方法可以确定为什么触发了布局循环?
如果屏幕上的任何文本字段都没有被修改,似乎不会触发布局(请参阅Finding the cause of a layout request in a ViewGroup)。修改 TextField 是否总是会触发重新布局?我可以以某种方式锁定它以防止这种情况吗?想到改变屏幕上任何地方的任何 TextField 都会导致整个测量/布局循环在整个应用程序中级联,这令人沮丧。它正在扼杀我的表现。
容器是一个自定义 ViewGroup 类,但我认为这不是问题所在。我看不出我可以做些什么不同的事情来防止它被调用。
我正在考虑向我的小部件添加“锁定”方法,以防止在初始布局之后发生任何进一步的布局更改。这将提高性能,但我宁愿解决根本问题。
这是调用 onMeasure() 方法时的堆栈:
Gridbox.onMeasure(int, int) 行:217
Gridbox(View).measure(int, int) 行:8171
FrameLayout(ViewGroup).measureChildWithMargins(View, int, int, int, int) 行:3132
FrameLayout.onMeasure(int, int) 行:245
FrameLayout(View).measure(int, int) 行:8171
PhoneWindow$DecorView(ViewGroup).measureChildWithMargins(View, int, int, int, int) 行:3132
PhoneWindow$DecorView(FrameLayout).onMeasure(int, int) 行:245
PhoneWindow$DecorView(View).measure(int, int) 行:8171
ViewRoot.performTraversals() 行:801
ViewRoot.handleMessage(Message) 行:1727
ViewRoot(Handler).dispatchMessage(Message) 行:99
Looper.loop() 行:123
ActivityThread.main(String[]) 行:4627
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) 行:不可用 [本机方法]
Method.invoke(Object, Object...) 行:521
ZygoteInit$MethodAndArgsCaller.run() 行:858
ZygoteInit.main(String[]) 行:616
NativeStart.main(String[]) 行:不可用 [本机方法]
【问题讨论】: