Question

I am having an awkward issue (may be for me). I am using the timer to perform Tcp listner and socket programming. I am opening a socket to listen any data present on the port sent from another Android device (working correctly) regularly. I have created 2 applications to test the data receiving, one is just dummy and second is my main application. I am getting exception in my main application but not in the dummy application.

Exception is : android.os.NetworkonMainThreadException

The code is exactly same in both apps here it is

onCreate() contains

timer2 = new Timer();
        timer2.schedule(new TimerTask() {           
            @Override
            public void run() {
                TimerMethod();
            }

        }, 0, 1000);

TimerMethod() is as follows

private void TimerMethod()
    {
        this.runOnUiThread(Timer_Tick);
    }

Timer_Tick is:

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

        }
    };

And the main Tcp method to listen the data on the port

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

The exception i am getting is when i am calling the runTcpServer() in Timer_Tick

Was it helpful?

Solution 2

You are running network related operation on the main ui thread. You should use Asynctask or create a new thread.

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

Check the above link

I suggest you use asynctask.

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

Use Asynctask and move your runTcpServer(). Also remember you cannot update ui from a background thread. You will have to use runOnUiThread or update ui in onPostExecute

Move all your network related operation to doInbackground(). Move the below to onPostExecute(). You can return the result of computation in doInbackground(). Based on the result update ui in onPostExecute

    TextView tv= (TextView) findViewById(R.id.textView2);
        //Log.d("TcpServer", "received: " + incomingMsg);
    tv.append(incomingMsg);

OTHER TIPS

This is the error

   this.runOnUiThread(Timer_Tick);

Never run network task in UI thread(Main thread)!

Or use this to enable network task in UI thread, but it is not fair

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

StrictMode.setThreadPolicy(policy); 

The error is visible you are executing timer on UI Thread this.runOnUiThread(Timer_Tick);, Network operation should always be performed on Worker Thread, instead just do new Thread(new Timer_Tick()).start();, executing network operation(as they are long running process) cause UI to not respond till network operation is complete.

Addition I saw this is android question, You can use AsyncTask See http://developer.android.com/reference/android/os/AsyncTask.html After Android OS 2.3 Network Operation on UI thread is not allowed

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top