我下面是我在Android上接收多播Wifi数据的代码。我正在使用像下面这样的runnable来更新GUI,但我发现有些数据包丢失了。我正在使用此代码来接收倒计时消息,但倒计时不是连续的。我不知道由于GUI更新的风格或由于某些其他问题而导致数据包丢失。请你们提出建议。
package com.example.cdttiming;
public class MainActivity extends Activity
{
EditText time;
String s;
Button button;
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);
//wm.setWifiEnabled(true);
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)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void startProgress(View view) {
Runnable runnable = new Runnable() {
@Override
public void run() {
while(true)
{
try
{
ms.receive(dp);
s = new String(dp.getData(),0,dp.getLength());
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
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;
}
}
答案 0 :(得分:1)
您无法访问主UI线程。这就是为什么你不能将文本设置为UI视图元素。
访问UI线程的方法很少 1)使用Activity.runOnUiThread()
this.runOnUiThread( new Runnable() { @Override
public void run() {
time.setText(s);
} })
2)我认为在你的情况下最好使用Handler对象,它是你的工作线程和主UI线程之间的桥梁
private Handler handler = new Handler(){
@Override
public void handleMessage(Message message) {
switch (message.what) {
case SET_TEXT:{
time.setText(s);
}break;
}
...
handler.sendEmptyMessage(SET_TEXT);