类似或相同的问题已在此处得到解答
我正在创建一个 Android 应用程序,它向网络发送广播消息并准备响应的设备列表。
现在我做了什么:
我创建了一个调用线程的Activity
类。
负责发送广播消息。DeviceManagerWindow.java
Sender.java
Sender.java
然后DeviceManagerWindow.java
调用另一个负责监听设备响应的线程。devices
设备响应后,响应将在 Activity 中列出。为此,我有一个TableLayout
名为deviceList
.
我写了什么代码:
DeviceManagerWindow.java This method is called when a button for search is pressed
public void searchDevice(View v) throws IOException, InterruptedException
{
//Log.v("TableLayout:",view.toString());
sendMulticastFlyport = new Thread(new FlyportSender(MAC));
sendMulticastFlyport.start();
new Thread()
{
public void run()
{
MulticastSocket socketComputer=null;
try
{
socketComputer = new MulticastSocket(WifiConstants.COMPUTER_RECV_PORT);
socketComputer.joinGroup(InetAddress.getByName(WifiConstants.COMPUTER_NETWORK_ADDR));
socketComputer.setSoTimeout(1*60*1000);
byte[] inBufComputer = new byte[1024];
DatagramPacket inPacketComputer = new DatagramPacket(inBufComputer, inBufComputer.length);
while(true)
{
System.out.println("Listening...");
socketComputer.receive(inPacketComputer);
System.out.println("Received");
String msg = new String(inBufComputer, 0, inPacketComputer.getLength());
DeviceInformation device = new DeviceInformation(1, msg, inPacketComputer.getAddress().toString());
addDevice(device, false, 1);
Log.v("Received:","Received Computer From :" + inPacketComputer.getAddress() + " Msg : " + msg);
//System.out.write(inPacket.getData(),0,inPacket.getLength());
System.out.println();
Thread.sleep(2000);
}
}
catch(Exception e)
{
Log.v("Exception:","During Receiving Computer: "+e.toString());
try
{
addDevice(null, true, 1);
}
catch (IOException e1)
{
Log.v("Exception:", "Computer End Error: " +e1);
}
}
finally
{
socketComputer.close();
}
}
}.start();
以下代码创建一个列表:
public void addDevice(DeviceInformation device, boolean bool, int type) throws IOException
{
TableLayout tb = (TableLayout) findViewById(R.id.DeviceList);
Log.v("addDevice","Called");
if(bool)
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
System.out.println(tb);
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
String message;
Log.v("addDevice","Device Timeout");
switch(type)
{
case 1:
computerEnd=true;
break;
case 2:
raspberryEnd=true;
break;
case 3:
flyportEnd=true;
break;
}
if(computerEnd && raspberryEnd && flyportEnd)
{
if(rowCounter>0)
{
message = "No More Devices";
}
else
{
message = "No Devices Found";
}
tv.setText(message);
tv.setTextColor(Color.WHITE);
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
tv.setVisibility(1);
tr.addView(tv);
tb.addView(tr);
}
}
else
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
Log.v("addDevice","Received");
String textToDisplay = device.getDeviceTypeString()+"\n"+device.getIPAddress(); //Write the text to display
tv.setText(textToDisplay);
tv.setTextColor(Color.WHITE);
Drawable img;
if(device.getDeviceType()==1)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.pc);
}
else if(device.getDeviceType()==2)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.raspberry);
}
else
{
img = getApplicationContext().getResources().getDrawable(R.drawable.flyport);
}
img.setBounds(0,0,70,45);
tv.setCompoundDrawables(null, null, img, null);
tv.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
}
});
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
rowCounter++;
Log.v("Result","Device Added");
}
}
现在它在 logCat 中向我显示一个错误:
05-11 22:01:10.165: E/AndroidRuntime(13873): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
我从中得出的结论是只允许 UIThread 访问创建的视图。
以前我试过:
new Thread()
{
public void run()
{
runOnUiThread(){
MulticastSocket socketComputer=null;
try
{
....
....
....
}
}
那个时候我收到一个错误:
主线程无法访问网络
在此之前,我曾尝试使用synchronized
从Receiving.java
线程文件中调用的方法。但它也给出了不创建列表的错误。
我已经尝试了所有可能的方法。
现在我该怎么办。?