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中發佈時,我將流作爲參數並使用它。

這似乎解決了這個問題。如果有人想觸摸它,請做!