27

アプリケーションを実行すると、電話の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);
         ...

setTextメソッドをコメントアウトすることにより、CPU使用率は予想されるレベルの約4%に低下します。このメソッドは毎秒呼び出され、同じ負荷超過を引き起こすことなくImageViews、CustomViews...を更新します。CPU使用率に加えて、dalvikは、setText()を呼び出すだけで、約10〜1000個のオブジェクトのガベージコレクションを常に報告します。

次のようなトレースファイルを作成します。

Debug.startMethodTracing("setText");
c.mTxtPosition.setText(position);
Debug.stopMethodTracing();

traceviewは、以下のメソッドをそれぞれの専用CPU%でトップ5としてリストします。

  • ViewParent.invalidateChildInParent(16%)
  • View.requestLayout(11%)
  • ViewGroup.invalidateChild(9%)
  • TextView.setText(7%)
  • トップレベル(6%)

誰かがこれについての説明がありますか?

4

5 に答える 5

22

少し前に気づきましたが、問題は、setTextを呼び出すたびにテキストボックスのサイズが変わる可能性があるため、画面全体がリレーアウト(高価)になる必要があることだと思います。

私はまだこれを試していませんが、テキストボックスが単純で、比較的固定サイズにできる場合は、TextViewをサブクラス化して、setTextでサイズを変更せず、可能な限り描画するビューを作成してみてください。既存のエリアに?それは多くの時間を節約するでしょう。

おそらく、これを実行できるsetTextのフラグがすでに存在しますが、詳しく検索していませんが、私はそれを認識していません。

于 2012-05-29T19:13:56.157 に答える
3

In my case, I update a TextView from touch event, which cause a lot of updating The solution was to change the TextView layout_width & layout_height to fixed sized.

于 2014-05-22T05:52:01.113 に答える
1

some possible improvements :

  1. try using a handler which updates the textview every 0.5 seconds instead of a thread that does it.
  2. make the runnable a final constant object instead of craeting a new one every second.
  3. consider checking that the time has changed (newTimeInMs-LastPublishedTimeInMs>=1000) before telling the textview to update itself.
  4. instead of String.format , try using StringBuilder . however , you won't enjoy the locale solution that the String.format gives (for example , for arabic digits) .
于 2012-05-29T19:24:45.937 に答える
0

In my case it was this property of TextView:

android:ellipsize="marquee"

Removing it speeded up setting text.

于 2016-01-16T13:23:42.367 に答える
0

If you look at the source code of setText method you can see that it does a lot of heavy lifting - there is measuring, drawing and object allocations, all of which run on the main thread.

You can use the new PrecomputedText API in order to do all of this on the background thread and make setText faster.

You can use the following working example using kotlin & coroutines

private fun TextView.setTextAsync(text: String) {
    val textView = this
    lifecycleScope.launch {
        val params = TextViewCompat.getTextMetricsParams(textView)
        val precomputedText = withContext(Dispatchers.Default) {
            PrecomputedTextCompat.create(text, params)
        }
        TextViewCompat.setPrecomputedText(textView, precomputedText)
    }
}

For more details you can read an article about it on my blog https://androidexplained.github.io/android/ui/2020/10/21/improving-textview-settext-performance.html

于 2020-10-25T20:07:38.750 に答える