我有一个尴尬的问题(可能适合我)。我正在使用计时器来执行Tcp列表器和套接字编程。我打开一个套接字来监听从另一个Android设备(正常工作)发送的端口上的任何数据。我创建了2个应用程序来测试数据接收,一个是虚拟的,第二个是我的主要应用程序。我在主应用程序中遇到异常,但在虚拟应用程序中没有异常。
例外是:android.os.NetworkonMainThreadException
这两个应用程序中的代码完全相同
onCreate()
包含
timer2 = new Timer();
timer2.schedule(new TimerTask() {
@Override
public void run() {
TimerMethod();
}
}, 0, 1000);
TimerMethod()
如下
private void TimerMethod()
{
this.runOnUiThread(Timer_Tick);
}
Timer_Tick
是:
private Runnable Timer_Tick = new Runnable() {
public void run() {
try
{
runTcpServer();
}
catch(Exception a)
{
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(a.toString());
}
}
};
用于侦听端口数据的主要Tcp方法
public void runTcpServer()
{
ServerSocket ss = null;
try {
ss = new ServerSocket(TCP_SERVER_PORT);
//ss.setSoTimeout(10000);
//accept connections
Socket s = ss.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
//receive a message
String incomingMsg = in.readLine() + System.getProperty("line.separator");
TextView tv= (TextView) findViewById(R.id.textView2);
//Log.d("TcpServer", "received: " + incomingMsg);
tv.append(incomingMsg);
//send a message
String outgoingMsg = "goodbye from port " + TCP_SERVER_PORT + System.getProperty("line.separator");
out.write(outgoingMsg);
out.flush();
Log.d("TcpServer", "sent: " + outgoingMsg);
//textDisplay.append("sent: " + outgoingMsg);
//SystemClock.sleep(5000);
s.close();
} catch (InterruptedIOException e) {
//if timeout occurs
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally {
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
Log.d("Error",e.toString());
}
}
}
}
我得到的例外情况是我在runTcpServer()
Timer_Tick
时
答案 0 :(得分:2)
这是错误
this.runOnUiThread(Timer_Tick);
永远不要在UI线程(主线程)中运行网络任务!
或者使用它在UI线程中启用网络任务,但这不公平
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
答案 1 :(得分:1)
您正在主ui线程上运行与网络相关的操作。您应该使用Asynctask或创建一个新线程。
http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html
检查以上链接
我建议你使用asynctask。
http://developer.android.com/reference/android/os/AsyncTask.html
使用Asynctask并移动runTcpServer()
。还记得你无法从后台线程更新ui。您必须使用runOnUiThread
或更新onPostExecute
将所有与网络相关的操作移至doInbackground()。将下面的内容移动到onPostExecute()。您可以在doInbackground()中返回计算结果。基于onPostExecute中的结果更新ui
TextView tv= (TextView) findViewById(R.id.textView2);
//Log.d("TcpServer", "received: " + incomingMsg);
tv.append(incomingMsg);
答案 2 :(得分:1)
错误是可见的,你正在UI线程this.runOnUiThread(Timer_Tick);
上执行计时器,网络操作应始终在工作线程上执行,而只是执行新的Thread(new Timer_Tick()).start();
,执行网络操作(因为它们是长时间运行的进程)导致UI在网络操作完成之前不响应。
<强>加成强> 我看到这是android问题,你可以使用AsyncTask看看http://developer.android.com/reference/android/os/AsyncTask.html Android OS 2.3网络操作不允许在UI线程上