0

我知道我在日志猫中遇到的异常有一个非常直接的名字。我唯一的问题是,我无法确定是什么原因导致我的例外。我创建了一个PC-Android多客户聊天。java.lang.ArrayIndexOutOfBoundsException真的很奇怪

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

我得到的唯一问题是,当我连接到android,clientArea(跟踪所有连接的用户)时,没有跟踪其他名称,而是多个android客户端用户名。 即。我仅在Android上使用用户名:Jurko连接,clientArea将有两个人称为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) 

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. 
     } 
    } 












} 

服务器(在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     

} 
+3

哪一行是MyActivity的175?异常stacktrace消息指定这是你的异常的来源:'at com.example.JurkoAndroidChat.MyActivity $ ServerTask.onProgressUpdate(MyActivity.java:175)' –

+0

参见 2014-06-19 08:37:35

回答

5

唯一的例外是clear.-

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 

告诉您,您正尝试访问index 2位置,该位置长度仅为2(位置01)。

我猜线MyActivity.java:175是这个one.-

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

,所以你需要检查this.-

data = stream.split("µ"); 

,并检查stream String有预期值(它应该有至少有两个µ字符会导致3+项的数组)。

+0

非常感谢,我有一种感觉,那是什么意思,只是不知道我应该如何处理它。 –

1

让我们先从错误消息:

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 

我们在其他地方知道你有长度为2的数组,但你已经走了过它的结束,因为Java数组索引从0length - 1范围。

可能的解释:

data阵列与此呼叫初始化:

data = stream.split("µ"); 

然而,如果没有在stream至少2个µ字符,则该数组将大于3短,并且此行将抛出异常:

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

检查data.length在进入此之前一段代码,确保它至少有3个,如果不是,则适当地处理错误。

1

您的stream还没有2 µ个字符,所以split返回的数组少于3个项目。当以下代码尝试使用data[2]时,此元素超出数组的范围并引发异常。

让您的代码更具防御性,并不总是假设收到的数据是正常的。 VG,拆分后,添加以下代码

if (data.length < 3) { 
    // Process error (log, user message, whatever) 
    return; 
} 
0

我得出一个结论,是否有人是有同样的问题,因为我,一些谁​​回答我的问题的专业的的可能想知道的为了增加它的知识。

首先,我双重检查正被发送的每个消息包含2分μ的,因此不存在的方式,数据[]可具有一个尺寸小于3

然而,我与插座工作在的AsyncTask(你必须或你得到NetworkTaskOnMainThread异常),当我初始化套接字和读写器之后,我在套接字连接时调用了publishProgess。我意识到不知何故,通过使用whileLoop可能会有一些差异,然后根据可能来回变化的内容调用进度,即。 2个用户同时发送消息。因此,我将AsyncTask的参数从<Void, Void, Void>更改为<Void, String, Void>,然后当我在doInBackground中发布时,我将流作为参数并使用它。

这似乎解决了这个问题。如果有人想触摸它,请做!