java - Existing TCP socket class throw NetworkOnMainThreadException when updated to new API -
this question has answer here:
i have inherited android application , updating latest api. getting networkonmainthreadexception
when create socket. have read number of solutions use asynctask
. asynctask
should used short running tasks. standard tcp connection last life of running application. bi-directional.
how dod update class using threads don't exception , able send data on socket?
public class tcpconnection { enum state { closed, closing, open }; state _state; socket _socket; //data stream head-unit datainputstream _inputstream; //data stream head-unit dataoutputstream _outputstream; receiver _receiver; thread _thread; ontcpdatareceivedlistener _ontcpdatareceived; public tcpconnection() { _state = state.closed; } // listen informed of data has been received tcp / ip socket. public void setontcpdatareceivedlistener(ontcpdatareceivedlistener listener) { _ontcpdatareceived = listener; } // used inform listener data has been received tcp / ip socket. public interface ontcpdatareceivedlistener { public void ontcpdatareceived(byte[] buffer, int length); } // try connecting given tcp / ip connection. // notes: // blocks until connection 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: 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: better error handling ex.printstacktrace(); } } public synchronized void close() { _state = state.closing; if (_socket != null && !_socket.isclosed()) { try { _socket.close(); } catch(ioexception ex) { //todo: 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(); } { if (_socket != null && !_socket.isclosed()) { try { _socket.close(); } catch (ioexception ex) { //todo: need error handling ex.printstacktrace(); } } } _state = state.closed; } }
}
you have couple of choices:
- update actual android class uses
tcpconnection
wrap callstcpconnection
in separate thread: createexecutor
, use that. - add
executor
instancetcpconnection
handles transmission , reception. expect issueconnect
function: maybe try wrapping code in separate runnable , launching on thread?
Comments
Post a Comment