Android 更新 Thread 和 Runnable 中的 TextView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12716850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 11:31:06  来源:igfitidea点击:

Android update TextView in Thread and Runnable

androidmultithreadingtextviewrunnable

提问by user1718339

I want to make a simple timer in Android that updates a TextView every second. It simply counts seconds like in Minesweeper.

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

The problem is when i ignore the tvTime.setText(...) (make it //tvTime.setText(...), in LogCat will be printed the following number every second. But when i want to set this number to a TextView (created in another Thread), the program crashes.

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

Does anyone have an idea how to solve this easily?

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

Here's the code (method is called on startup):

这是代码(方法在启动时调用):

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();
}

EDIT:

编辑:

Finally, I got it. Here is the solution, for those who are interested in.

最后我明白了。这是解决方案,对于那些有兴趣的人。

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();
}

回答by Chris Conway

The UserInterface can only be updated by the UI Thread. You need a Handler, to post to the UI Thread:

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();
}

回答by dennisdrew

Alternatively, you can also just do this in your thread whenever you want to update a UI element:

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

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

回答by Jorgesys

As an option use runOnUiThread()to change de views properties in the main thread.

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

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

回答by zienkikk

You cannot access UI elements from non-UI threads. Try surrounding the call to setText(...)with another Runnableand then look into the View.post(Runnable)method.

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