Android 异步任务和套接字未关闭

Android 异步任务和套接字未关闭,android,multithreading,sockets,android-asynctask,Android,Multithreading,Sockets,Android Asynctask,在你把这个标为复制品之前,请听我说完。我从StackOverflow的成员那里得到了以前的建议,但我仍然无法实现这一点,但我已经改进了我的代码,并限制了可能出现的问题,但我不明白我做错了什么。仅供参考:这是我正在制作的客户端服务器聊天程序的客户端。我已经制作了PC版的服务器和客户端,完全可以正常工作 我相信这可能是问题的根源。如果查看ServerTask类(当按下connect按钮时执行),它看起来好像没有启动套接字?有人能帮我吗?如果有人能帮助这个毫无希望的初学者,我将不胜感激 这可能没有帮助

在你把这个标为复制品之前,请听我说完。我从StackOverflow的成员那里得到了以前的建议,但我仍然无法实现这一点,但我已经改进了我的代码,并限制了可能出现的问题,但我不明白我做错了什么。仅供参考:这是我正在制作的客户端服务器聊天程序的客户端。我已经制作了PC版的服务器和客户端,完全可以正常工作

我相信这可能是问题的根源。如果查看ServerTask类(当按下connect按钮时执行),它看起来好像没有启动套接字?有人能帮我吗?如果有人能帮助这个毫无希望的初学者,我将不胜感激

这可能没有帮助,但这里也是AndroidManifest.xml,因为我看到了需要设置权限的地方

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.JurkoAndroidChat"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="16"/>
    <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">

        <activity android:name="MyActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>




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;
    ServerTask serverTask;

    @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);
                    serverTask = new ServerTask();
                    serverTask.execute();


                } 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();
                        serverTask.printToStream("hey");

                    } catch (Exception e) {
                        chatArea.append("Message was not sent.\n" + e);
                    }
                    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);

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

        public void printToStream(String message) {
            try {
                out.println(message);
                out.flush();
            } catch (Exception e) {chatArea.append(e + "\n"); }


        }

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

    }

    public class streamTask extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... voids) {
            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();}
            return null;  //To change body of implemented 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.

        }
    }

    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');
        }
    }








}

包com.example.JurkoAndroidChat;
导入android.app.Activity;
导入android.content.DialogInterface;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.util.Log;
导入android.widget.Button;
导入android.widget.EditText;
导入android.widget.TextView;
导入android.view.view;
导入java.net。*;
导入java.io.*;
导入java.util.*;
公共类MyActivity扩展了活动{
/**
*在首次创建活动时调用。
*/
//在这里,我们将main.xml表单的组件连接到代码
按钮连接按钮、断开按钮、发送按钮;
文本视图聊天区,客户区;
EditText消息字段、用户名字段、ipField;
//额外变量和套接字
字符串用户名,serverIP;
int端口=5000;
插座;
打印输出;
缓冲读取器;
ArrayList用户列表;
布尔值未连接=假;
服务器任务服务器任务;
@凌驾
创建时的公共void(Bundle savedInstanceState){
System.out.println(“工作?”);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
userList=newarraylist();
connectButton=(按钮)findViewById(R.id.Button);
sendButton=(按钮)findViewById(R.id.button1);
disconnectButton=(按钮)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(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
//要更改已实现方法的主体,请使用文件|设置|文件模板。
如果(断开连接==错误){
username=usernameField.getText().toString();
usernameField.setFocusable(false);
usernameField.setClickable(false);
serverIP=ipField.getText().toString();
ipField.setFocusable(假);
ipField.setClickable(假);
serverTask=newservertask();
serverTask.execute();
}else if(未连接==真){
append(“您已经连接到服务器。\n”);
}
}
});
disconnectButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
//要更改已实现方法的主体,请使用文件|设置|文件模板。
字符串bye=(username+“::Disconnect”);
试一试{
打印(再见);
out.flush();
附加(“已断开连接。\n”);
sock.close();
}catch(异常e){e.printStackTrace();}
断开连接=错误;
usernameField.setFocusable(true);
usernameField.setClickable(true);
ipField.setFocusable(真);
ipField.setClickable(真);
clientArea.setText(“”);
}
});
sendButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图){
//要更改已实现方法的主体,请使用文件|设置|文件模板。
字符串nothing=“”;
if((messageField.getText().toString().equals(nothing))){
messageField.setText(“”);
messageField.requestFocus();
}否则{
试一试{
out.println(用户名+“:”+messageField.getText().toString()+“:”+“聊天”);
out.flush();
serverTask.printToStream(“嘿”);
}捕获(例外e){
append(“消息未发送。\n”+e);
}
messageField.setText(“”);
messageField.requestFocus();
}
}
});
}
公共类ServerTask扩展了AsyncTask{
@凌驾
受保护的空位背景(空位…空位){
试一试{
Log.i(“Asynctask”、“doInBackground”);
sock=新套接字(serverIP,端口);
out=新的PrintWriter(sock.getOutputStream());
in=新的BufferedReader(新的InputStreamReader(sock.getInputStream());
println(用户名+”:“+”已连接。“+”:“+”连接”);
out.flush();
断开连接=正确;
}捕获(例外情况除外){
//append(“无法连接到端口“+port+”+ex处的“+serverIP+”);
//
protected Void doInBackground(Void... voids) {
            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();
            }
            return null; // To change body of implemented methods use File |
                            // Settings | File Templates.
        }