Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
972 views
in Technique[技术] by (71.8m points)

android - Updating UI / runOnUiThread / final variables: How to write lean code that does UI updating when called from another Thread

I have been reading up on the UI updating when I found out that, like WinForms, Android need to do UI updates on from the main thread (too bad, I was hoping someone could once and for all solve that irritating problem).

Anyways, I need to pass that to the UI thread. Some suggest the use of the runOnUiThread method and that might have worked, if it wasn't for that irritating "final" that then came into play.

I have an Interface, with a method I cannot change. It looks like this:

@Override
public void connStateChange(ClientHandler clientHandler)

That method is called when I get a change in the connection status (network). When I do, I need to do some stuff, and in this case it is adding some text to a TextView.

So I tried this, but of course the variable "clientHandler" isn't final:

@Override
public void connStateChange(ClientHandler clientHandler) {

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

How do I in a nice, clean and efficient way write code in this example to update the UI? I need access to all my variables etc...

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Try it:

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

By the way, code becomes more readable, if you declare not anonim class right in the method, but declare inner class out of methods. Consider it as pattern Command.

Example of more clean and reusable code.

@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() + "
"); 
               if (clientHandler.state == State.Connected) {
                    tv.append("Loginserver hittad");         
               }       
         } 

}

Though the Runnable implementation itself was inflated a little, code became more re-usable and easy to read.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...