web-dev-qa-db-fra.com

Mise à jour Android TextView dans Thread and Runnable

Je veux créer une simple minuterie dans Android qui met à jour une TextView chaque seconde. Il compte simplement en secondes comme dans Minesweeper.

Le problème est quand j'ignore la tvTime.setText (...) (rendez-la //tvTime.setText (...), dans LogCat sera imprimé le numéro suivant toutes les secondes . Mais quand je veux définir ceci numéro à un TextView (créé dans un autre thread), le programme se bloque.

Quelqu'un a-t-il une idée pour résoudre ce problème facilement?

Voici le code (la méthode est appelée au démarrage):

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

MODIFIER:

Enfin, je l’ai eu ... Voici la solution, pour ceux qui sont intéressés.

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

L'interface utilisateur ne peut être mise à jour que par le thread d'interface utilisateur. Vous avez besoin d'un Handler , pour poster sur le fil de l'interface utilisateur:

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

Sinon, vous pouvez également le faire dans votre fil de discussion chaque fois que vous souhaitez mettre à jour un élément d'interface utilisateur:

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

En option, utilisez runOnUiThread () pour modifier les propriétés de vues dans le fil principal.

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

Vous ne pouvez pas accéder aux éléments d'interface utilisateur à partir de threads non-UI. Essayez d’entourer l’appel de setText(...) avec une autre Runnable puis examinez la méthode View.post(Runnable) .

0
zienkikk