更新多个Textbox Java GUI

时间:2013-07-22 14:57:16

标签: java android multithreading user-interface

我有一个活动或表单,其中有一个名为time的文本框。正如本论坛专家所建议的那样,我使用runnable来从wifi接收数据时更新TextBox。

我怀疑当我想要更新多个TextBox时该怎么做。我应该使用多个可运行的块,如

              time1.post(new Runnable() {
                @Override
                public void run() {
                    time2.setText(s1);
                }
              });

             time2.post(new Runnable() {
                @Override
                public void run() {
                    time2.setText(s2);
                }
              });

            time3.post(new Runnable() {
                @Override
                public void run() {
                    time3.setText(s2);
                }
              });

或者其他一些技术可以更新多个TextBox?我现在的代码如下。

package com.example.cdttiming;

public class MainActivity extends Activity
{
    EditText time;
    String s;
    Button button;
    byte[] buffer = new byte[65535];
    InetAddress ia = null;
     byte[] bmessage = new byte[1500];
     DatagramPacket dp = new DatagramPacket(bmessage, bmessage.length);
     MulticastSocket ms = null;
    @Override

    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);     

        time = (EditText) findViewById(R.id.et_time);
    try 
        {
        WifiManager wm = (WifiManager)getSystemService(Context.WIFI_SERVICE); 
        WifiManager.MulticastLock multicastLock = wm.createMulticastLock("multicastLock");
        multicastLock.setReferenceCounted(true);        
        multicastLock.acquire();      

        ia = InetAddress.getByName("226.1.1.1");    
        try {
            ms = new MulticastSocket(4321);
            } catch (IOException e) {
            e.printStackTrace();
            }
        try {
            ms.joinGroup(ia);
            } catch (IOException e) {
            e.printStackTrace();
            }

        ms.setReuseAddress(true);

        }
           catch (UnknownHostException e)               {
                time.setText(e.getMessage());

            }
            catch (IOException e)                {
                time.setText(e.getMessage());
             }     
     }

    public void startProgress(View view) {
        Runnable runnable = new Runnable() {
          @Override
          public void run() {              
        while(true)             {
             try                 {
                // String str="This is test string";
                  ms.receive(dp);
                  s = new String(dp.getData(),0,dp.getLength()); 
                  char retval[] = s.toCharArray();
             }
             catch (UnknownHostException e)                 {
                 time.setText(e.getMessage());

                }
               catch (IOException e)                    {
                   time.setText(e.getMessage());
                }     

            ****////// My doubt is here if i have multple strings of data and multiple
            /// multiple textboxes to update then what to do ???****

             time.post(new Runnable() {
                @Override
                public void run() {
                    time.setText(s);

                }
              });
           }  // while
          }
        };
        new Thread(runnable).start();
      }

    @Override
     public boolean onCreateOptionsMenu(Menu menu)      {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }   
}

2 个答案:

答案 0 :(得分:0)

我建议你只创建一个runnable并在主线程上发布一次,如下所示:

      time1.post(new Runnable() {
        @Override
        public void run() {
            time2.setText(s1);
            time2.setText(s2);
            time3.setText(s3);
        }
      });

创建runnable并将其发布到视图的主线程处理程序上的需要只是关于在UI线程上运行一段代码。无论你从哪里获得主线程处理程序引用。

你也可以在主线程上创建你的处理程序:

protected void onCreate(Bundle savedInstanceState)
{
      this.uiThrdHandler = new Handler();
}

然后使用它发布一个runnable:

this.uiThrdHandler.post(new Runnable(){
        ...
});

当然不需要创建另一个处理程序,但它是出于演示目的。

Activity对象有一个实用方法:runOnUiThread

使用它,它将是:

  MainActivity.this.runOnUiThread (new Runnable() {
        @Override
        public void run() {
            time2.setText(s1);
            time2.setText(s2);
            time3.setText(s3);
        }
      });

但同样,结果是一样的。

答案 1 :(得分:0)

您的代码有点令人困惑。在主要 while 循环中的一个案例中,您捕获数据,将其分配给字符串变量 s ,然后使用文本小部件 post()函数和 Runnable EditText 小部件设置为该值。但是在同一个 while 循环中,您可以使用异常处理程序直接设置相同的 EditText 小部件。如果 while 循环在定时器循环有机会触发设置文本调用之前重置 s 的值,您的代码看起来可能会丢失消息。

您似乎正在尝试创建某种形式的实时系统,并且需要主 while 循环来持续处理,并在数据可用时显示数据。现在你有3个不同的消费者(文本小部件),但你没有提到你是否还有3个不同的消息来源,或者是否仍然只有一个主处理循环,某种形式的选择器将决定哪个文本小部件获取消息? / p>

如果我在这些方面构建一些东西,我可能会使用消息传递系统并遵循生产者 - 消费者模型。当收到文本时,我会让主处理循环将一个简单的2字段消息推送到包含对文本小部件的引用和对数据字符串的引用的队列。因为字符串在Java中是不可变的,所以一旦消息对象拥有自己的文本副本,对 s 的任何更改都不会影响消息。

然后,我会在后台运行第二个消耗消息队列的线程。它会将消息从队列中拉出,使用消息数据构建对目标文本小部件的 post 调用,将其关闭,然后返回以获取下一条消息。

通过这条路线,您可以将数据处理线程与UI更新处理分开,而无需担心需要更新多少文本小部件或其他小部件。如果您需要添加其他内容,则只需担心创建更新消息的代码所知的新窗口小部件。执行小部件更新的线程不知道您拥有多少个小部件,它只使用消息创建者所说的更新消息对象中引用的小部件。