我正在尝试使用AsynchronousSocketChannel
通过Android中的TCP / IP发送数据,但是却收到android.os.NetworkOnMainThreadException.
当我运行程序并尝试连接到服务器时,将执行失败的connect CompletionHandler方法,并给出NetworkOnMainThreadException
在Boost.Asio
中,我们在单独的线程中运行io_context
。在AsynchronousSocketChannel
中需要执行什么操作才能在单独的线程上运行它?
Ethernet.java:
public class Ethernet {
private String ip;
private int port;
private Queue<String> recvDataQueue, sendDataQueue;
private InetSocketAddress address;
private String readData;
private InputStream in;
private OutputStream out;
private AsynchronousSocketChannel socket;
private boolean socketAlive, connectionInProgress;
private ByteBuffer readBuffer, sendBuffer;
Ethernet(String ip, int port) {
if (port > 65535 && port < 1024)
port = 6666;
this.ip = ip;
this.port = port;
this.socketAlive = false;
connectionInProgress = false;
address = new InetSocketAddress(ip, port);
this.readBuffer = ByteBuffer.allocate(8192);
}
public boolean connect(){
try{
if(this.socketAlive)
return false;
connectionInProgress = true;
this.socket = AsynchronousSocketChannel.open();
this.socket.connect(this.address, null,
new CompletionHandler<Void, Object>() {
@Override
public void completed(Void result, Object attachment) {
socketAlive = true;
//connectionInProgress = false;
}
@Override
public void failed(Throwable e, Object attachment) {
socketAlive = false;
//connectionInProgress = false;
}
});
return true;
}
catch (Exception e){
String strErr = e.getMessage();
Log.e("Exception", strErr);
}
return false;
}
public long sendData(String writeData){
try{
//this.sendBuffer = ByteBuffer.allocateDirect(writeData.length());
this.sendBuffer = ByteBuffer.wrap(writeData.getBytes(), 0, writeData.length());
//this.socket.write(writeBuffer, 0, writeData.length()), null,
this.socket.write(this.sendBuffer, null,
new CompletionHandler <Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
if (result < 0) {
// handle unexpected connection close
socketAlive = false;
//connectionInProgress = false;
}
else if(result < sendBuffer.remaining()){
// got all data, process the buffer
sendBuffer.compact();
socket.write(sendBuffer, null, this); //Test
}
else{
}
}
@Override
public void failed(Throwable e, Object attachment) {
if(socket.isOpen()){
try{
socketAlive = false;
socket.close();
}
catch (Exception ex){
String strErr = e.getMessage();
Log.e("Exception", strErr);
}
}
}
});
}
catch (Exception e){
String strErr = e.getMessage();
Log.e("Exception", strErr);
}
return -1;
}
private void recieveDataSocket() throws Exception {
this.socket.read(this.readBuffer, null, new CompletionHandler<Integer, Object>() {
@Override
public void completed(Integer result, Object attachment) {
if (result < 0) {
socketAlive = false;
}
else {
//recvQueue.add(readBuffer.toString());
}
}
@Override
public void failed(Throwable e, Object attachment) {
if(socketAlive && socket.isOpen()) {
try {
socketAlive = false;
//connectionInProgress = false;
socket.close();
}
catch (final Exception ex){
}
}
}
});
}
public void disconnect(){
try {
if(this.socket.isOpen() && this.socketAlive)
this.socket.close();
}
catch (final Exception ex){
String strErr = ex.getMessage();
Log.e("Exception", strErr);
}
}
}
}
MainActivity.java
Ethernet eth = new Ethernet("192.168.1.22", 6666);
while(true) {
if(!eth.isSocketAlive() && !eth.isConnectionInProgress())
eth.connect();
if(!eth.isSocketAlive())
continue;
eth.sendData("Hello, World!!!\n");
eth.disconnect();
}