【问题标题】:Updating UI / runOnUiThread / final variables: How to write lean code that does UI updating when called from another Thread更新 UI / runOnUiThread / final 变量:如何编写从另一个线程调用时更新 UI 的精简代码
【发布时间】:2015-01-14 17:01:33
【问题描述】:

当我发现像 WinForms 一样,Android 需要从主线程进行 UI 更新时,我一直在阅读 UI 更新(太糟糕了,我希望有人能一劳永逸地解决这个恼人的问题) .

无论如何,我需要将它传递给 UI 线程。有些人建议使用 runOnUiThread 方法,如果不是因为那个恼人的“final”然后起作用的话,那可能会奏效。

我有一个接口,但我无法更改其方法。它看起来像这样:

@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");
        }
      }
   });
}

在这个示例中,我如何以一种漂亮、简洁和高效的方式编写代码来更新 UI?我需要访问我的所有变量等...

【问题讨论】:

    标签: android user-interface final


    【解决方案1】:

    试试看:

    @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");         
                   }       
             }    
        }); 
    } 
    

    顺便说一句,如果您不在方法中声明匿名类,而是在方法中声明内部类,代码变得更具可读性。将其视为模式命令。

    更干净且可重用的代码示例。

    @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 实现本身有点夸张,但代码变得更加可重用且易于阅读。

    【讨论】:

    • 我实际上觉得匿名类,直接在方法中,比我遇到的其他任何东西都要清晰得多。但是,我不确定命令模式是什么,所以我会研究一下。
    • 如你所愿。至于我,我倾向于编写可重用和斯巴达式的代码。类内类比方法内类更灵活。此外,方法变得更加紧凑。
    • 你能链接到一些清楚的例子,这样我就明白了?因为我不认为我是 =)
    • 对不起,没有链接 :) 我会重新写答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多