[英]Error: android.os.NetworkOnMainThreadException while using asynctask
I am having a problem with creating a socket and sending messages from an android app to a raspberry pi. 我在创建套接字并将消息从android应用发送到树莓派时遇到问题。 I used this example from the following site: http://android-er.blogspot.nl/2016/05/android-client-example-2-communicate.html , this to understand how sockets work. 我从以下站点使用了此示例: http : //android-er.blogspot.nl/2016/05/android-client-example-2-communicate.html ,这是为了了解套接字的工作方式。 But while I use AsyncTask, I still get an android.os.NetworkOnMainThreadException. 但是当我使用AsyncTask时,我仍然收到了android.os.NetworkOnMainThreadException。 This is my MainActivity: 这是我的MainActivity:
public class MainActivity extends AppCompatActivity {
EditText editTextAddress, editTextPort, editTextMsg;
Button buttonConnect, buttonDisconnect, buttonSend;
TextView textViewState, textViewRx;
ClientHandler clientHandler;
ClientThread clientThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.address);
editTextPort = (EditText) findViewById(R.id.port);
editTextMsg = (EditText) findViewById(R.id.msgtosend);
buttonConnect = (Button) findViewById(R.id.connect);
buttonDisconnect = (Button) findViewById(R.id.disconnect);
buttonSend = (Button)findViewById(R.id.send);
textViewState = (TextView)findViewById(R.id.state);
textViewRx = (TextView)findViewById(R.id.received);
buttonDisconnect.setEnabled(false);
buttonSend.setEnabled(false);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
buttonDisconnect.setOnClickListener(buttonDisConnectOnClickListener);
buttonSend.setOnClickListener(buttonSendOnClickListener);
clientHandler = new ClientHandler(this);
}
View.OnClickListener buttonConnectOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
MainActivity.this.startService(new Intent(MainActivity.this,
ClientThread.class));
clientThread = new ClientThread(
editTextAddress.getText().toString(),
Integer.parseInt(editTextPort.getText().toString()),
clientHandler);
clientThread.execute();
buttonConnect.setEnabled(false);
buttonDisconnect.setEnabled(true);
buttonSend.setEnabled(true);
}
};
View.OnClickListener buttonDisConnectOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(clientThread != null){
clientThread.setRunning(false);
}
}
};
String msgToSend;
View.OnClickListener buttonSendOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(clientThread != null){
msgToSend = editTextMsg.getText().toString();
clientThread.txMsg(msgToSend);
}
}
};
private void updateState(String state){
textViewState.setText(state);
}
private void updateRxMsg(String rxmsg){
textViewRx.append(rxmsg + "\n");
}
private void clientEnd(){
clientThread = null;
textViewState.setText("clientEnd()");
buttonConnect.setEnabled(true);
buttonDisconnect.setEnabled(false);
buttonSend.setEnabled(false);
}
public static class ClientHandler extends Handler {
public static final int UPDATE_STATE = 0;
public static final int UPDATE_MSG = 1;
public static final int UPDATE_END = 2;
private MainActivity parent;
public ClientHandler(MainActivity parent) {
super();
this.parent = parent;
}
@Override
public void handleMessage(Message msg) {
switch (msg.what){
case UPDATE_STATE:
parent.updateState((String)msg.obj);
break;
case UPDATE_MSG:
parent.updateRxMsg((String)msg.obj);
break;
case UPDATE_END:
parent.clientEnd();
break;
default:
super.handleMessage(msg);
}
}
}
}
This the ClientThread.java code: 这是ClientThread.java代码:
public class ClientThread extends AsyncTask<Void, Void, Void>{
String dstAddress;
int dstPort;
private boolean running;
MainActivity.ClientHandler handler;
Socket socket;
PrintWriter printWriter;
BufferedReader bufferedReader;
public ClientThread(String addr, int port, MainActivity.ClientHandler handler) {
super();
dstAddress = addr;
dstPort = port;
this.handler = handler;
}
public void setRunning(boolean running){
this.running = running;
}
private void sendState(String state){
handler.sendMessage(
Message.obtain(handler,
MainActivity.ClientHandler.UPDATE_STATE, state));
}
public void txMsg(String msgToSend){
if(printWriter != null){
printWriter.println(msgToSend);
}
}
@Override
protected Void doInBackground(Void... arg0) {
System.out.println("In doinbackground");
sendState("connecting...");
running = true;
try {
socket = new Socket(dstAddress, dstPort);
sendState("connected");
OutputStream outputStream = socket.getOutputStream();
printWriter = new PrintWriter(outputStream, true);
InputStream inputStream = socket.getInputStream();
InputStreamReader inputStreamReader =
new InputStreamReader(inputStream);
bufferedReader = new BufferedReader(inputStreamReader);
while (running) {
//bufferedReader block the code
String line = bufferedReader.readLine();
if (line != null) {
handler.sendMessage(
Message.obtain(handler,
MainActivity.ClientHandler.UPDATE_MSG, line));
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (printWriter != null) {
printWriter.close();
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
handler.sendEmptyMessage(MainActivity.ClientHandler.UPDATE_END);
return null;
}
}
This is the error I'm getting: 这是我得到的错误:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.zerocj.projectsocked, PID: 2415
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
at java.net.SocketOutputStream.write(SocketOutputStream.java:157)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:295)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.io.BufferedWriter.flush(BufferedWriter.java:254)
at java.io.PrintWriter.newLine(PrintWriter.java:482)
at java.io.PrintWriter.println(PrintWriter.java:629)
at java.io.PrintWriter.println(PrintWriter.java:740)
at com.example.zerocj.projectsocked.ClientThread.txMsg(ClientThread.java:47)
at com.example.zerocj.projectsocked.MainActivity$3.onClick(MainActivity.java:85)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
You're calling your txMsg()
method from a click listener which runs on the UI thread. 您是通过在UI线程上运行的点击监听器调用txMsg()
方法的。 And this method seems to be writing to a Writer
that wired up to a socket. 而且此方法似乎正在写入连接到套接字的Writer
。
If your wanna exchange messages back and forth between background thread and UI thread, maybe a better idea that an AsyncTask
would be a Thread
with Looper
and handlers to pass the messages along from one thread to the other. 如果您想在后台线程和UI线程之间来回交换消息,可能更好的主意是AsyncTask
将是一个带有Looper
和处理程序的Thread
,以将消息从一个线程传递到另一个线程。
Please check your stack trace. 请检查您的堆栈跟踪。 It says use strict mode in your code 它说在代码中使用严格模式
int SDK_INT = android.os.Build.VERSION.SDK_INT;
if (SDK_INT > 8)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
// Where you get exception write that code inside this.
}
Thanks hope this help you. 希望对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.