简体   繁体   English

错误:使用asynctask时出现android.os.NetworkOnMainThreadException

[英]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.

相关问题 android.os.NetworkOnMainThreadException进入AsyncTask - android.os.NetworkOnMainThreadException into AsyncTask AsyncTask中的android.os.NetworkOnMainThreadException - android.os.NetworkOnMainThreadException in AsyncTask Android asynctask json解析发生错误android.os.NetworkOnMainThreadException - Android asynctask json parsing getting error android.os.NetworkOnMainThreadException android.os.NetworkOnMainThreadException错误,即使在AsyncTask中运行 - android.os.NetworkOnMainThreadException error even when running in AsyncTask android.os.NetworkOnMainThreadException但我使用了AsyncTask - android.os.NetworkOnMainThreadException but i used AsyncTask 中的Android.OS.NetworkOnMainThreadException - Android.OS.NetworkOnMainThreadException in android.os.NetworkOnMainThreadException在Android上使用rxjava - android.os.NetworkOnMainThreadException using rxjava on android 即使在AsyncTask中运行,也会出现“ android.os.NetworkOnMainThreadException” - “android.os.NetworkOnMainThreadException” even when running in AsyncTask 改造 - android.os.NetworkOnMainThreadException - Retrofit - android.os.NetworkOnMainThreadException 使用 Okhttp 从 PHP 脚本中获取数据时遇到 android.os.NetworkOnMainThreadException - Encountering android.os.NetworkOnMainThreadException while fetching data from a PHP script using Okhttp
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM