0

我遇到了一个尴尬的问题(可能对我来说)。我正在使用计时器来执行 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

4

3 回答 3

2

这是错误

   this.runOnUiThread(Timer_Tick);

永远不要在 UI 线程(主线程)中运行网络任务!

或者用这个在UI线程中启用网络任务,但是不公平

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();

StrictMode.setThreadPolicy(policy); 
于 2013-06-19T05:25:15.680 回答
1

您正在主 ui 线程上运行与网络相关的操作。您应该使用 Asynctask 或创建一个新线程。

http://developer.android.com/reference/android/os/NetworkOnMainThreadException.html

检查上面的链接

我建议你使用异步任务。

http://developer.android.com/reference/android/os/AsyncTask.html

使用 Asynctask 并移动您的runTcpServer(). 另请记住,您不能从后台线程更新 ui。您将不得不使用runOnUiThread或更新 uionPostExecute

将所有与网络相关的操作移至 doInbackground()。将以下内容移至 onPostExecute()。您可以在 doInbackground() 中返回计算结果。基于 onPostExecute 中的结果更新 ui

    TextView tv= (TextView) findViewById(R.id.textView2);
        //Log.d("TcpServer", "received: " + incomingMsg);
    tv.append(incomingMsg);
于 2013-06-19T05:25:51.197 回答
1

错误是可见的,您正在 UI Thread 上执行计时器this.runOnUiThread(Timer_Tick);,网络操作应始终在 Worker Thread 上执行,而不是只执行 new Thread(new Timer_Tick()).start();,执行网络操作(因为它们是长时间运行的进程)导致 UI 在网络操作完成之前无法响应。

另外 我看到这是android问题,你可以使用AsyncTask见http://developer.android.com/reference/android/os/AsyncTask.html After Android OS 2.3 Network Operation on UI thread is not allowed

于 2013-06-19T05:31:07.633 回答