Android 每x秒更改线程上TextView元素上的文本

Android 每x秒更改线程上TextView元素上的文本,android,textview,Android,Textview,我想制作一个每1秒执行一次的线程,定期执行的函数必须修改一个TextView对象,该对象对应于用户界面的xml元素。我现在向您展示代码: public class MainActivity extends Activity{ //Object which will be modified by the thread public TextView distance; public void onCreate(Bundle savedInstanceState){ supe

我想制作一个每1秒执行一次的线程,定期执行的函数必须修改一个TextView对象,该对象对应于用户界面的xml元素。我现在向您展示代码:

public class MainActivity extends Activity{

  //Object which will be modified by the thread
  public TextView distance;

  public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    distance = (TextView)findViewById(R.id.distance);

    //Declaring 1-second periodic thread
    ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
    exec.scheduleAtFixedRate(
      new Runable(){
        @Override
        public void run(){
          System.out.println("works before"); //Just for debugging
          Random random = new Random();
          distance.setText("" + random.nextInt(100));
          System.out.println("works afterwards"); //Just for debugging
        }
      }
    , 0, 1, TimeUnit.SECONDS);
  }
但问题是,当我运行此代码时,设置TextView对象上文本的行只执行一次,Eclipse上调试日志上的结果如下所示:

System.out: works before
System.out: works afterwards
System.out: works before
在这里它仍然被阻止,但在应用程序中还有一个按钮,甚至线程被阻止,我可以交互并执行这个按钮启动的功能。为确保在更改TextView的值时出现问题,请在这一行上注释代码:

...
        public void run(){
          System.out.println("works before"); //Just for debugging
          Random random = new Random();
          //distance.setText("" + random.nextInt(100));
          System.out.println("works afterwards"); //Just for debugging
        }
...
调试日志上的结果是:

System.out: works before
System.out: works afterwards
System.out: works before
System.out: works afterwards
System.out: works before
System.out: works afterwards

而且它永远不会结束(每秒钟重复一次),我对android结构的了解还不是很深入,所以如果有人能告诉我错误在哪里,谢谢!)

我无法理解为什么在第一种情况下应用程序没有崩溃。在第一种情况下,您需要在UI线程上运行
setText
,但计时器在另一个线程中运行。这个问题很容易解决。。只需使用
处理程序
在UI线程上发布即可。另一方面,您可以考虑使用处理程序及其
postDelayed
方法的可能性。主要优势在于它在UI线程上运行,并且对于不太繁重的计算,可以使用它

您不能从UI线程外部更新UI。不管怎么说,只使用处理程序更容易

    final Handler mUIHandler = new Handler(Looper.getMainLooper());
    mUIHandler.post(new Runnable() {
        Random random = new Random();

        @Override
        public void run() {
            distance.setText("" + random.nextInt(100));
            mUIHandler.postDelayed(this, 1000);                    
        }
    });

我使用了您编写的代码,问题解决了,谢谢您的帮助!:)我使用了Handler和postDelayed方法的解决方案,效果很好,谢谢!)