1

我有一个活动或表单,其中有一个名为 time 的文本框。正如该论坛的专家所建议的那样,我在从 wifi 接收数据时使用 runnable 来更新 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);
                }
              });

还是有其他技术可以更新多个文本框?我现在的代码如下所示。

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;
    }   
}
4

2 回答 2

0

我建议你只创建一个可运行文件并在主线程上发布一次,如下所示:

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

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

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

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

然后使用它发布一个可运行的:

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

但同样,结果是一样的。

于 2013-07-22T15:47:46.867 回答
0

你的代码有点混乱。在您的主要while循环中的一种情况下,您正在捕获数据,将其分配给 String 变量s然后使用文本小部件post()函数和RunnableEditText小部件设置为该值。但是在同一个while循环中,您有异常处理程序,它们只是直接设置相同的EditText小部件。如果while循环在计时器循环有机会触发 set text 调用之前重置s的值,您的代码看起来也可能会丢失消息。

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

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

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

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

于 2013-07-22T15:49:00.297 回答