Обновление UI / runOnUiThread / final переменные: как написать скудный код, который выполняет обновление пользовательского интерфейса при вызове из другого потока - PullRequest
2 голосов
/ 01 октября 2011

Я читал об обновлении пользовательского интерфейса, когда узнал, что, как и WinForms, Android должен делать обновления пользовательского интерфейса из основного потока (очень плохо, я надеялся, что кто-то может раз и навсегда решить эту раздражающую проблему).

В любом случае, мне нужно передать это потоку пользовательского интерфейса.Некоторые предлагают использовать метод runOnUiThread, и это могло бы сработать, если бы не тот раздражающий «финал», который затем вступил в игру.

У меня есть Интерфейс, метод которого я не могу изменить.Это выглядит так:

@Override
public void connStateChange(ClientHandler clientHandler)

Этот метод вызывается, когда я получаю изменение в состоянии соединения (сеть).Когда я это делаю, мне нужно что-то делать, и в этом случае он добавляет текст в TextView.

Итак, я попробовал это, но, конечно, переменная "clientHandler" не является окончательной:

@Override
public void connStateChange(ClientHandler clientHandler) {

   runOnUiThread(new Runnable()
   {
      public void run()
      {
        tv.append(clientHandler.getIP() + ", " + clientHandler.state.toString() + "\n");
        if (clientHandler.state == State.Connected)
        {
            tv.append("Loginserver hittad");
        }
      }
   });
}

Как в этом примере написать хороший, чистый и эффективный код для обновления пользовательского интерфейса?Мне нужен доступ ко всем моим переменным и т.д ...

1 Ответ

4 голосов
/ 01 октября 2011

Попробуйте:

@Override 
public void connStateChange(ClientHandler clientHandler) {
    final ClientHandler temporaryHander = clientHandler;
    runOnUiThread(new Runnable() {
         public void run() {
               tv.append(temporaryHandler.getIP() + ", " + temporaryHandler.state.toString() + "\n"); 
               if (temporaryHandler.state == State.Connected) {
                    tv.append("Loginserver hittad");         
               }       
         }    
    }); 
} 

Кстати, код становится более читабельным, если вы объявляете не anonim класс прямо в методе, а объявляете внутренний класс вне методов. Считайте это шаблоном Command.

Пример более чистого и многократно используемого кода.

@Override 
public void connStateChange(ClientHandler clientHandler) {
    final ClientHandler temporaryHander = clientHandler;
    runOnUiThread(new MyRunnableCommand(temporaryHandler)); 
} 

private class MyRunnableCommand implements Runnable { 

     private ClientHandler clientHandler;

     public MyRunnableCommand(ClientHandler clientHandler) {
         this.clientHandler = clientHandler;
     }

     @Override
     public void run() {
               tv.append(clientHandler.getIP() + ", " + clientHandler.state.toString() + "\n"); 
               if (clientHandler.state == State.Connected) {
                    tv.append("Loginserver hittad");         
               }       
         } 

}

Хотя сама реализация Runnable была немного раздута, код стал более пригодным для повторного использования и легким для чтения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...