Search code examples
javaandroidtcpnetworkonmainthread

Network on MainThread Exception (One app is working, other one throwing exception)


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


Solution

  • 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);