未显示定期更新的文本

时间:2017-01-31 01:49:14

标签: java android for-loop settext

我有一个for循环,我想调用setText方法。除了在脚本运行完成之前文本不会更改的事实之外,这没有任何错误。我想要它做的是每次调用setText方法时更改代码。我在下面附上我的代码,应该是相当紧张的前进。 代码:

package com.example.zoe.andone;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void startLoop(View view) {
        String string = getString(R.string.hello);
        ((TextView)findViewById(R.id.hello)).setText("starting...");
        for (int i = 0; i < 10; i++) {
            String updated = Integer.toString(i);
            ((TextView)findViewById(R.id.hello)).setText(updated);
            try {
                Thread.sleep(250);
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
        }
        ((TextView)findViewById(R.id.hello)).setText("done!");
    }
}

3 个答案:

答案 0 :(得分:1)

所谓的&#34;丢帧&#34;。

是时候学习了!

在回答之前,让我们解释一下这里发生了什么。

你可能已经知道android的帧速率为60fps(每秒60帧),这意味着每隔1/60秒渲染一次屏幕并显示给用户(为了提供最佳清晰度)。它通过在你的应用程序上运行一些渲染代码(以及其他任何需要渲染的东西)每1/60秒来计算显示的屏幕在这个特定的ms上应该是什么样子(它的's&#39; s被称为框架。)

然而,执行此操作的代码正在UI线程上运行,如果您在渲染刻度开始时执行任何操作,则android框架只会丢弃该帧(它不会计算它)。 在你的情况下,Thread.sleep(250);是导致你的帧被丢弃的原因,因为它在你的for循环的每次迭代中持有UI线程250毫秒(所以它的250毫秒*(10 - 1) ),这是很多帧。

删除框架意味着在UI上看不到更新。

<强>解决方案

您应该安排更新任务每250毫秒运行一次,而不是使用Thread.sleep(250);并删除帧。那就是它。

private int i = 0; // Does the trick!
public void startLoop(View view) {
    String string = getString(R.string.hello);
    ((TextView)findViewById(R.id.hello)).setText("starting...");
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                if (i < 10) {
                    String updated = Integer.toString(i);
                    i++;
                    updateHelloOnUiThread(updated);
                } else {
                    updateHelloOnUiThread("done!");
                    handler.removeCallbacksAndMessages(null);
                    i = 0; // For future usages
                }
            }
        },250);
}

private void updateHelloOnUiThread(final String text) {
     MainActivity.this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ((TextView)findViewById(R.id.hello)).setText(text);
            }
     });
}

进一步阅读

Android UI : Fixing skipped frames

High Performance Android Apps, Chapter 4. Screen and UI Performance

答案 1 :(得分:1)

this.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                int globalTimer = 0;

                int limitTimer = 10;
                int i = 0;

                // create Timer
                Timer timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        globalTimer++;
                        //run your code
                        ((TextView)findViewById(R.id.hello)).setText(i+"");
                        i++;
                        //check if globalTimer is equal to limitTimer
                        if (globalTimer == limitTimer) {
                            timer.cancel(); // cancel the Timer
                        }
                    }

                }, 0, 250);
            }
        });

答案 2 :(得分:0)

问题是,您在UI线程上调用Thread.sleep。 如果线程处于休眠状态,则无法更新UI(屏幕上显示的内容)。