35

TextView を毎秒更新するシンプルなタイマーを Android で作成したいと考えています。マインスイーパのように秒数をカウントするだけです。

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

4 に答える 4

54

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();
}
于 2012-10-03T21:21:00.113 に答える
32

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

runOnUiThread(new Runnable() {
    public void run() {
        // Update UI elements
    }
});
于 2012-10-03T21:23:50.397 に答える
1

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

于 2012-10-03T21:21:13.910 に答える