【问题标题】:Android update TextView in Thread and RunnableAndroid 在 Thread 和 Runnable 中更新 TextView
【发布时间】:2012-09-24 20:59:03
【问题描述】:

我想在 Android 中制作一个简单的计时器,每秒更新一个 TextView。它只是像扫雷一样计算秒数。

问题是当我忽略 tvTime.setText(...) 时(使其成为 //tvTime.setText(...),在 LogCat 中将每秒打印以下数字。 但是当我想将此数字设置为 TextView(在另一个线程中创建)时,程序崩溃了。

有人知道如何轻松解决这个问题吗?

代码如下(启动时调用方法):

private void startTimerThread() {
    Thread th = new Thread(new Runnable() {
        private long startTime = System.currentTimeMillis();
        public void run() {
            while (gameState == GameState.Playing) {
                System.out.println((System.currentTimeMillis() - this.startTime) / 1000);
                tvTime.setText("" + ((System.currentTimeMillis() - this.startTime) / 1000));
                try {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    th.start();
}

编辑:

终于,我明白了。 以下是解决方案,有兴趣的朋友可以参考一下。

private void startTimerThread() {       
    Thread th = new Thread(new Runnable() {
        private long startTime = System.currentTimeMillis();
        public void run() {
            while (gameState == GameState.Playing) {                
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvTime.setText(""+((System.currentTimeMillis()-startTime)/1000));
                    }
                });
                try {
                    Thread.sleep(1000);
                } 
                catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    th.start();
}

【问题讨论】:

  • 感谢 bud,这帮助很大!
  • 但是当你点击返回按钮时它会崩溃

标签: android multithreading textview runnable


【解决方案1】:

作为一个选项,使用runOnUiThread() 在主线程中更改视图属性。

  runOnUiThread(new Runnable() {
        @Override
        public void run() {       
                textView.setText("Stackoverflow is cool!");
        }
    });

【讨论】:

    【解决方案2】:

    或者,您也可以在您想要更新 UI 元素时在您的线程中执行此操作:

    runOnUiThread(new Runnable() {
        public void run() {
            // Update UI elements
        }
    });
    

    【讨论】:

    • 这是不好的做法吗?使用 Handler 更好?
    • yes..handler 是一个更好的选择。Handler 来自 API 1。
    【解决方案3】:

    您无法从非 UI 线程访问 UI 元素。尝试用另一个Runnable 包围对setText(...) 的调用,然后查看View.post(Runnable) 方法。

    【讨论】:

      【解决方案4】:

      UserInterface 只能由 UI 线程更新。您需要Handler,才能发布到 UI 线程:

      private void startTimerThread() {
          Handler handler = new Handler();
          Runnable runnable = new Runnable() {
              private long startTime = System.currentTimeMillis();
              public void run() {
                  while (gameState == GameState.Playing) {  
                      try {
                          Thread.sleep(1000);
                      }    
                      catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                      handler.post(new Runnable(){
                          public void run() {
                             tvTime.setText("" + ((System.currentTimeMillis() - this.startTime) / 1000));
                      }
                  });
                  }
              }
          };
          new Thread(runnable).start();
      }
      

      【讨论】:

      • 在我的例子中,有一个文本视图位于一行列表视图中;无法更新其文本属性...有什么建议吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-02
      • 2011-05-21
      • 2017-05-14
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多