【问题标题】:android.os.NetworkOnMainThreadException chat program on tablet [duplicate]平板电脑上的android.os.NetworkOnMainThreadException聊天程序[重复]
【发布时间】:2013-10-08 23:45:21
【问题描述】:

简而言之,我一直在使用简单的套接字和打印编写器制作 PC Android 聊天。我有 PC 客户端和服务器工作,我不能去工作是 android 因为我真的很陌生。当我尝试连接时,任何人都可以帮我解决这个错误吗?

仅供参考:我确实在 google 和 stackoverflow 上的 asynctask 的其余部分上进行了查找,但没有什么是清楚的。我试图了解它是如何工作的,但没有一个例子接近。我更改了代码,因此我的 connectButton onClickListener 启动了一个新的 ServerTask(这是 AsyncTask),并将它放入我曾经在 onClickListener 上使用的代码中。我不得不注释掉异常,因为它正在写入 doInBackground 中的 UI,这显然是不可能的。我只是不明白为什么我启动了新的 AsyncTask 就无法连接

    package com.example.JurkoAndroidChat;

import android.app.Activity;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.view.View;

import java.net.*;
import java.io.*;
import java.util.*;



public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    // Right here, we connecting the components of the main.xml form to code
    Button connectButton, disconnectButton, sendButton;
    TextView chatArea, clientArea;
    EditText messageField, usernameField, ipField;

    //Extra variables and sockets
    String username, serverIP;
    int Port = 5000;
    Socket sock;
    PrintWriter out;
    BufferedReader in;
    ArrayList<String> userList;
    Boolean isConnected = false;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        System.out.println("Working?");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        userList = new ArrayList();
        connectButton = (Button)findViewById(R.id.button);
        sendButton = (Button)findViewById(R.id.button1);
        disconnectButton = (Button)findViewById(R.id.button2);

        chatArea = (TextView)findViewById(R.id.textView2);
        clientArea = (TextView)findViewById(R.id.textView3);

        messageField = (EditText)findViewById(R.id.editText2);
        usernameField = (EditText)findViewById(R.id.editText);
        ipField = (EditText)findViewById(R.id.editText1);

        connectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //To change body of implemented methods use File | Settings | File Templates.
                if (isConnected == false) {
                    username = usernameField.getText().toString();
                    usernameField.setFocusable(false);
                    usernameField.setClickable(false);
                    serverIP = ipField.getText().toString();
                    ipField.setFocusable(false);
                    ipField.setClickable(false);
                    executeTask();

                } else if (isConnected == true) {
                    chatArea.append("You are already connected to the server.\n");
                }
            }
        });

        disconnectButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //To change body of implemented methods use File | Settings | File Templates.
                String bye = (username + ": :Disconnect");
                try {
                    out.print(bye);
                    out.flush();
                    chatArea.append("Disconnected.\n");
                    sock.close();

                } catch (Exception e) {e.printStackTrace();}
                isConnected = false;
                usernameField.setFocusable(true);
                usernameField.setClickable(true);
                ipField.setFocusable(true);
                ipField.setClickable(true);
                clientArea.setText("");
            }
        });

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //To change body of implemented methods use File | Settings | File Templates.
                String nothing = "";
                if ((messageField.getText().toString().equals(nothing))) {
                    messageField.setText("");
                    messageField.requestFocus();
                } else {
                    try {
                        out.println(username + ":" + messageField.getText().toString() + ":" + "Chat");
                        out.flush();
                    } catch (Exception e) {
                        chatArea.append("Message was not sent.\n");
                    }
                    messageField.setText("");
                    messageField.requestFocus();
                }
            }
        });


    }

    public class ServerTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            try {
                Log.i("Asynctask", "doInBackground");
                sock = new Socket(serverIP, Port);
                out = new PrintWriter(sock.getOutputStream());
                in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
                out.println(username + ":" + "has connected." + ":" + "Connect");
                out.flush();
                isConnected = true;

            } catch (Exception ex) {
//                    chatArea.append("Unable to connect to " + serverIP + " at port " + Port + "." + ex);
//                    ex.printStackTrace();
//                    usernameField.setFocusable(true);
//                    usernameField.setClickable(true);
//                    ipField.setFocusable(true);
//                    ipField.setClickable(true);

            }


                ListenThread();
            return null;  //To change body of implemented methods use File | Settings | File Templates.
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
           //To change body of overridden methods use File | Settings | File Templates.
        }

    }

    public void executeTask() {
        new ServerTask().execute();
    }

    public class IncomingReader implements Runnable {
        @Override
        public void run() {
            //To change body of implemented methods use File | Settings | File Templates.
            String[] data;
            String stream, done = "Done", connect = "Connect", disconnect = "Disconnect", chat = "Chat";

            try {
                while ((stream = in.readLine()) != null) {
                    data = stream.split(":");

                    if (data[2].equals(chat)) {
                        chatArea.append(data[0] + ": " + data[1] + '\n');
                    } else if (data[2].equals(connect)) {
                        chatArea.setText("");
                        userAdd(data[0]);
                    } else if (data[2].equals(disconnect)) {
                        userRemove(data[0]);
                    } else if (data[2].equals(done)) {
                        clientArea.setText("");
                        writeUsers();
                        userList.clear();
                    }


                }
            }  catch (Exception e) {e.printStackTrace();}
        }
    }

    public void ListenThread() {
        Thread IncomingReader = new Thread(new IncomingReader());
        IncomingReader.start();
    }



    public void userAdd(String data) {
        userList.add(data);
    }

    public void userRemove(String data) {
        chatArea.append(data + " has disconnected from the server.\n");
        for (String token:userList)
            if (token.equals(data))
                userList.remove(token);
    }

    public void writeUsers() {
        String[] tempList = new String[(userList.size())];
        userList.toArray(tempList);
        for (String token:tempList) {
            clientArea.append(token + '\n');
        }
    }








}

【问题讨论】:

  • 那是...一千个其他问题的副本。只需谷歌NetworkOnMainThreadException
  • 虽然你几乎不需要。异常 name 是不言自明的,如果这对您没有帮助,请阅读它的 Javadoc。

标签: java android multithreading sockets networkonmainthread


【解决方案1】:

您不能在主线程上进行联网,您必须创建一个新线程或AsyncTask 才能进行任何联网操作。

http://developer.android.com/reference/android/os/AsyncTask.html

【讨论】:

  • 你是说你不能在AsyncTask做网络?
  • 谢谢,我没发现我打字太快了。已编辑!
  • 编辑为与 AsyncTask 一起使用。我了解它是如何工作的,但我仍然很困惑为什么我无法连接/这如何影响我发送消息。这是我的理解。单击连接:启动一个新的 AsyncTask,它就像一个不同的线程,因此它应该解决 NetworkOnMainThread 问题:然后 ListenThread() 执行另一个线程来解析消息。这一切都应该仍在运行,是的还是垃圾收集以某种方式捡起它?非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2014-09-18
相关资源
最近更新 更多