I have inherited an Android application and am updating it for the latest API.
I am getting the NetworkOnMainThreadException when I create the socket. I have read a number of solutions that say to use AsyncTask. However AsyncTask should only be used for short running Tasks. This is a standard TCP connection that will last for the life of the running application. It is bi-directional. 
How dod I update the class using Threads so that I don't get the exception and am able to send data over the socket?
public class TcpConnection
{
    enum State
{
    Closed,
    Closing,
    Open
};
State _state;    
Socket _socket;
//data stream from the head-unit
DataInputStream _inputStream;
//data stream to the head-unit
DataOutputStream _outputStream;
Receiver _receiver;
Thread _thread;
OnTcpDataReceivedListener _onTcpDataReceived;
public TcpConnection()
{                 
     _state = State.Closed;
}
// Listen to this to be informed of what data has been received from a TCP / IP socket.
public void setOnTcpDataReceivedListener(OnTcpDataReceivedListener listener)   
{
    _onTcpDataReceived = listener;
}
// Used to inform the listener that data has been received from a TCP / IP socket.
public interface OnTcpDataReceivedListener
{
    public void onTcpDataReceived(byte[] buffer, int length);
}
// Try connecting to a given TCP / IP connection.
// Notes:
// Blocks until a connection is created.
// if connected
public synchronized void connect(String ipAddress, int port) 
throws IOException
{
    if (_state != State.Closed)
        return;
    try
    {
        _state = State.Open;
        _socket = new Socket(ipAddress, port);
        _inputStream = new DataInputStream(_socket.getInputStream());
        _outputStream = new DataOutputStream(_socket.getOutputStream());            
    }
    catch(IOException ex)
    {            
        //TODO: do better error handling
        ex.printStackTrace();
        if (_socket != null) {
            _socket.close();
            _socket = null;             
        }
        if (_inputStream != null) {
            _inputStream.close();
            _inputStream = null;
        }
        if (_outputStream != null) {
            _outputStream.close();
            _outputStream = null;
        }
        throw ex;
    }
    _receiver = new Receiver();
    _thread = new Thread(_receiver);
    _thread.setName("TcpConnection.Receiver");
    _thread.start();
}
public void write(byte[] buffer)
{
    if (_state != State.Open)
        return;
    try
    {
        _outputStream.write(buffer);
    }
    catch(IOException ex)
    {            
        //TODO: do better error handling
        ex.printStackTrace();            
    } 
}
public synchronized void close()
{
    _state = State.Closing;
    if (_socket != null && !_socket.isClosed())
    {
        try
        {
            _socket.close();
        }
        catch(IOException ex)
        {
            //TODO: do better error handling
            ex.printStackTrace();
        }
    }         
}
private class Receiver implements Runnable
{                                  
    @Override
    public void run() 
    {                        
        try 
        {
            byte[] buffer = new byte[512];
            int read = 0;
            while(_state == State.Open)
            {                    
                read = _inputStream.read(buffer);
                if (read > 0)
                {
                    if (_onTcpDataReceived != null)
                    {
                        _onTcpDataReceived.onTcpDataReceived(buffer, read);
                    }
                }
            }
        }
        catch (SocketException ex)
        {
            if (    !(_state != State.Open 
                    && ex.getMessage() != null 
                    && ex.getMessage().equalsIgnoreCase("socket closed")))
            {
                ex.printStackTrace();
            }
        }
        catch (IOException ex) 
        {
            //TODO: need error handling
            ex.printStackTrace();
        }            
        finally 
        {
            if (_socket != null && !_socket.isClosed())
            {
                try
                {
                    _socket.close();
                }
                catch (IOException ex) 
                {
                    //TODO: need error handling
                    ex.printStackTrace();
                }                    
            }
        }
        _state = State.Closed;
     }
}   
}
 
     
    