java.lang.ArrayIndexOutOfBoundsException真的很奇怪

Jur*_*uba 0 java sockets android android-asynctask indexoutofboundsexception

我知道我在日志猫中获得的异常有一个非常严格的名字.我唯一的问题是我无法确定导致我的异常的原因.我创建了一个PC-Android多客户聊天.

PC版本与服务器和客户端100%一起工作.我实现了从PC客户端到Android客户端和聊天工作相同的技术.

我得到的唯一问题是,当我连接android,clientArea(跟踪所有连接的用户)时,不跟踪其他名称,而是跟踪android客户端用户名的倍数.即.我只使用用户名:Jurko连接到android,clientArea将有2个人称为Jurko而不是只有一个.

logcat的:

10-11 17:19:08.221: ERROR/AndroidRuntime(12379): FATAL EXCEPTION: main
        java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
        at com.example.JurkoAndroidChat.MyActivity$ServerTask.onProgressUpdate(MyActivity.java:175)
        at com.example.JurkoAndroidChat.MyActivity$ServerTask.onProgressUpdate(MyActivity.java:130)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:647)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4895)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:994)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:761)
        at dalvik.system.NativeStart.main(Native Method)
Run Code Online (Sandbox Code Playgroud)

Android客户端:

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 = new ArrayList();
    Boolean isConnected = false, exceptionCaught = false;

    ServerTask serverTask;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        System.out.println("Working?");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        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) {  } // nothing caught so far.
                isConnected = false;
                usernameField.setFocusable(true);
                usernameField.setClickable(true);
                usernameField.setFocusableInTouchMode(true);
                ipField.setFocusable(true);
                ipField.setFocusableInTouchMode(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) {
                        Log.e("Error", e.toString());
                        chatArea.append("Message was not sent.\n" + e);
                    }
                    messageField.setText("");
                    messageField.requestFocus();
                }
            }
        });

    }


    public class ServerTask extends AsyncTask<Void, Void, Void> {

        String[] data;
        String stream, done = "Done", connect = "Connect", disconnect = "Disconnect", chat = "Chat";
        @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) {
                    exceptionCaught = true;
                Log.e("Application", ex.toString());

            }
            try {
                while ((stream = in.readLine()) != null) {

                    publishProgress();
                }
            } catch (Exception e) {}

            return null;
        }

        public void writeUsers() {
            clientArea.setText("");
            Iterator<String> iterator = userList.iterator();
            while (iterator.hasNext()) {
                String token = iterator.next();
                clientArea.append(token + '\n');
            }
        }

        @Override
        protected void onProgressUpdate(Void... values) {

                    data = stream.split("µ");

                    if (data[2].equals(chat)) {
                        if (data[1].equals("has connected.") || data[1].equals("has disconnected."))
                            chatArea.append(data[0] + " " + data[1] + '\n');
                        else
                            chatArea.append(data[0] + ": " + data[1] + '\n');
                    } else if (data[2].equals(connect)) {
                        userList.add(data[0]);
                        writeUsers();
                    } else if (data[2].equals(disconnect)) {
                        userList.remove(data[0]);
                        writeUsers();
                    } else if (data[2].equals(done))
                        userList.clear();

           }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            if (exceptionCaught == true) {
                chatArea.append("Unable to connect to " + serverIP + " at port " + Port + ".\n");
                usernameField.setFocusable(true);
                usernameField.setClickable(true);
                usernameField.setFocusableInTouchMode(true);
                ipField.setFocusableInTouchMode(true);
                ipField.setFocusable(true);
                ipField.setClickable(true);
                exceptionCaught = false;

            }
                //To change body of overridden methods use File | Settings | File Templates.
        }
    }












}
Run Code Online (Sandbox Code Playgroud)

服务器(在PC上):

/*
 * To change this template, choose Tools : Templates
 * and open the template in the editor.
 */

/*
 * ServerWindow.java
 *
 * Created on Apr 23, 2011, 4:16:05 PM
 */


import java.io.*;
import java.net.*;
import java.util.*;
/**
 *
 * @author JurkoGuba
 */
public class ServerWindow extends javax.swing.JFrame {
    ArrayList clientOutputStreams;
    ArrayList<String> onlineUsers;

    public class ClientHandler implements Runnable  {
        BufferedReader reader;
        Socket sock;
        PrintWriter client;


        public ClientHandler(Socket clientSocket, PrintWriter user) {
            // new inputStreamReader and then add it to a BufferedReader
            client = user;
            try {
                sock = clientSocket;
                reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
            } // end try
            catch (Exception ex) {
                outputPane.append("Error beginning StreamReader. \n");
            } // end catch

        } // end ClientHandler()

        public void run() {
            String message, connect = "Connect", disconnect = "Disconnect", chat = "Chat" ;
            String[] data;

            try {
                while ((message = reader.readLine()) != null) {

                    outputPane.append("Received: " + message + "\n");
                    data = message.split("µ");

                    if (data[2].equals(connect)) {

                        tellEveryone((data[0] + "µ" + data[1] + "µ" + chat));
                        userAdd(data[0]);

                    } else if (data[2].equals(disconnect)) {

                        tellEveryone((data[0] + "µhas disconnected." + "µ" + chat));
                        userRemove(data[0]);

                    } else if (data[2].equals(chat)) {

                        tellEveryone(message);

                    } else {
                        outputPane.append("No Conditions were met. \n");
                    }


                } // end while
            } // end try
            catch (Exception ex) {
                outputPane.append("Lost a connection. \n");
                ex.printStackTrace();
                clientOutputStreams.remove(client);
            } // end catch
        } // end run()
    } // end class ClientHandler
    /** Creates new form ServerWindow */
    public ServerWindow() {
        initComponents();
    }



    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        outputPane = new javax.swing.JTextArea();
        startButton = new javax.swing.JButton();
        stopButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("House Server");

        outputPane.setColumns(20);
        outputPane.setEditable(false);
        outputPane.setLineWrap(true);
        outputPane.setRows(5);
        outputPane.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        jScrollPane1.setViewportView(outputPane);

        startButton.setText("Start");
        startButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                startButtonActionPerformed(evt);
            }
        });

        stopButton.setText("Stop");
        stopButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                stopButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addContainerGap()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                        .addGroup(layout.createSequentialGroup()
                                                .addComponent(startButton, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addGap(18, 18, 18)
                                                .addComponent(stopButton, javax.swing.GroupLayout.DEFAULT_SIZE, 183, Short.MAX_VALUE))
                                        .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE))
                                .addContainerGap())
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addGroup(layout.createSequentialGroup()
                                .addContainerGap()
                                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 229, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(18, 18, 18)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                                        .addComponent(startButton)
                                        .addComponent(stopButton))
                                .addContainerGap(19, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void startButtonActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:
        Thread starter = new Thread(new ServerStart());
        starter.start();

        outputPane.append("Server started. \n");
    }

    private void stopButtonActionPerformed(java.awt.event.ActionEvent evt) {
        // TODO add your handling code here:

        tellEveryone("Serverµis stopping and all users will be disconnected.\nµChat");
        outputPane.append("Server stopping... \n");

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerWindow().setVisible(true);
            }
        });
    }


    public class ServerStart implements Runnable {
        public void run() {
            clientOutputStreams = new ArrayList();
            onlineUsers = new ArrayList();

            try {
                ServerSocket serverSock = new ServerSocket(5000);

                while (true) {
                    // set up the server writer function and then begin at the same
                    // the listener using the Runnable and Thread
                    Socket clientSock = serverSock.accept();
                    PrintWriter writer = new PrintWriter(clientSock.getOutputStream());
                    clientOutputStreams.add(writer);

                    // use a Runnable to start a 'second main method that will run
                    // the listener
                    Thread listener = new Thread(new ClientHandler(clientSock, writer));
                    listener.start();
                    outputPane.append("Got a connection. \n");
                } // end while
            } // end try
            catch (Exception ex)
            {
                outputPane.append("Error making a connection. \n");
            } // end catch

        } // end go()
    }

    public void userAdd (String data) {
        String add = "µ µConnect", done = "Serverµ µDone", name = data;
        outputPane.append("Before " + name + " added. \n");
        onlineUsers.add(name);
        outputPane.append("After " + name + " added. \n");
        tellEveryone(done);

        Iterator<String> iterator = onlineUsers.iterator();
        while (iterator.hasNext()){
             String token = iterator.next();
             tellEveryone(token + add);
        }


    }

    public void userRemove (String user) {
        String add = "µ µDisconnect", done = "Serverµ µDone";
//        Iterator<String> remove = onlineUsers.iterator();
//        while (remove.hasNext()) {
//            String token = remove.next();
//            if (token.equals(user))
//                onlineUsers.remove(token);
//        }
        onlineUsers.remove(user);

        tellEveryone(user + add);
    }

    public void tellEveryone(String message) {
        // sends message to everyone connected to server
        Iterator it = clientOutputStreams.iterator();

        while (it.hasNext()) {
            try {
                PrintWriter writer = (PrintWriter) it.next();
                writer.println(message);
                outputPane.append("Sending: " + message + "\n");
                writer.flush();
                outputPane.setCaretPosition(outputPane.getDocument().getLength());

            } // end try
            catch (Exception ex) {
                outputPane.append("Error telling everyone. \n");
            } // end catch
        } // end while
    } // end tellEveryone()


    // Variables declaration - do not modify                     
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea outputPane;
    private javax.swing.JButton startButton;
    private javax.swing.JButton stopButton;
    // End of variables declaration                   

}
Run Code Online (Sandbox Code Playgroud)

ssa*_*tos 5

例外是明确的.-

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
Run Code Online (Sandbox Code Playgroud)

告诉你,你正试图访问index 2一个只有2(位置01)长度的数组中的位置.

我猜这条线MyActivity.java:175就是这一条.-

if (data[2].equals(chat)) {
Run Code Online (Sandbox Code Playgroud)

所以你需要复习一下.-

data = stream.split("µ");
Run Code Online (Sandbox Code Playgroud)

并检查它stream String是否具有预期值(它应至少有两个µ字符,以产生3个以上项目的数组).