简单的TextView.setText导致40%的CPU使用率

phl*_*bas 25 android cpu-usage

运行我的应用程序会导致我的手机上CPU使用率降低约40%:

final String position = String.format("%02d:%02d:%02d", time.getHours(), time.getMinutes(),
                time.getSeconds());
getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
         c.mTxtPosition.setText(position);
         ...
Run Code Online (Sandbox Code Playgroud)

通过注释掉setText方法,CPU使用率下降到~4%的预期水平.该方法每秒调用一次并刷新ImageViews,CustomViews ...而不会导致相同的负载过量.除了CPU使用率之外,dalvik通过调用setText()不断报告大约10-1000个对象的垃圾收集.

创建这样的跟踪文件:

Debug.startMethodTracing("setText");
c.mTxtPosition.setText(position);
Debug.stopMethodTracing();
Run Code Online (Sandbox Code Playgroud)

traceview按以下各自的CPU%列出以下方法作为前5名:

  • ViewParent.invalidateChildInParent(16%)
  • View.requestLayout(11%)
  • ViewGroup.invalidateChild(9%)
  • TextView.setText(7%)
  • 顶层(6%)

有人对此有解释吗?

Tim*_*Tim 21

我不久前注意到了这一点,我认为问题在于每次调用setText时,文本框的大小都会发生变化,因此整个屏幕需要重新布局(昂贵).

我自己还没有尝试过这个,但如果你的文本框很简单并且可以做成一个相对固定的大小,也许可以尝试将TextView子类化并创建一个不在setText上调整自身大小的视图,而只是绘制它可以做的任何事情.进入现有区域?这样可以节省很多时间.

也许theres已经是setText的标志,可以让它做到这一点,但我不知道它,虽然我没有仔细搜索过.

  • 谢谢,我的布局文件确实存在问题.最初TextView位于<include />布局中.我只是将它合并到主布局中,CPU%恢复正常.所以我们可以缩小范围,也许有一个特殊的包含属性/策略必须遵循以避免这种情况. (4认同)
  • @Tim你做了我的一天兄弟.特别是在使用列表视图时,建议使用固定大小的布局.我之前使用过"wrap_content",listview是如此滞后,一旦我将布局改为固定的dp值,速度变得快得多. (2认同)