web-dev-qa-db-ja.com

Android Thread and RunnableのTextViewを更新

AndroidでTextViewを1秒ごとに更新します。Minesweeperのように単純に秒をカウントします。

問題は、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();
}
33
user1718339

UserInterfaceは、UIスレッドによってのみ更新できます。 UIスレッドに投稿するには、 Handler が必要です。

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

または、UI要素を更新する場合はいつでもスレッドでこれを実行することもできます。

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

オプションとして runOnUiThread() を使用して、メインスレッドのビュープロパティを変更します。

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

非UIスレッドからUI要素にアクセスすることはできません。 setText(...)への呼び出しを別のRunnableで囲み、 View.post(Runnable) メソッドを調べてください。

0
zienkikk