简体   繁体   中英

Index Out of Bounds Exception - unexpected error

Among others, I am working with Parse.com integration and Sinch.com instant messaging integration. Upon clicking on a list item, an unexpected error is shown, and in particular, below is the log messages. Upon click, it was suppose to direct you to the instant messaging activity, however I receive the bellow error.

08-07 16:49:44.810: E/AndroidRuntime(11444): FATAL EXCEPTION: main
08-07 16:49:44.810: E/AndroidRuntime(11444): Process: com.dooba.beta, PID: 11444
08-07 16:49:44.810: E/AndroidRuntime(11444): java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
08-07 16:49:44.810: E/AndroidRuntime(11444):    at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at java.util.ArrayList.get(ArrayList.java:308)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.dooba.beta.MatchingActivity$3.done(MatchingActivity.java:90)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.parse.FindCallback.internalDone(FindCallback.java:45)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.parse.FindCallback.internalDone(FindCallback.java:1)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.parse.Parse$6$1.run(Parse.java:888)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at android.os.Handler.handleCallback(Handler.java:733)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at android.os.Handler.dispatchMessage(Handler.java:95)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at android.os.Looper.loop(Looper.java:136)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at android.app.ActivityThread.main(ActivityThread.java:5017)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at java.lang.reflect.Method.invokeNative(Native Method)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at java.lang.reflect.Method.invoke(Method.java:515)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
08-07 16:49:44.810: E/AndroidRuntime(11444):    at dalvik.system.NativeStart.main(Native Method)

Below is the activity code

public class MatchingActivity extends Activity {


    private String currentUserId;
    private ArrayAdapter<String> namesArrayAdapter;
    private ArrayList<String> names;
    private ListView usersListView;
    private Button logoutButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.matching);

        logoutButton = (Button) findViewById(R.id.logoutButton);
        logoutButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ParseUser.logOut();
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
            }
        });

        setConversationsList();
    }

    private void setConversationsList() {
        currentUserId = ParseUser.getCurrentUser().getObjectId();
        names = new ArrayList<String>();

        ParseQuery<ParseUser> query = ParseUser.getQuery();
        query.whereNotEqualTo("name", currentUserId);
        query.findInBackground(new FindCallback<ParseUser>() {
            public void done(List<ParseUser> userList, ParseException e) {
                if (e == null) {
                    for (int i=0; i<userList.size(); i++) {
                        names.add(userList.get(i).getUsername().toString());
                    }

                    usersListView = (ListView)findViewById(R.id.usersListView);
                    namesArrayAdapter =
                        new ArrayAdapter<String>(getApplicationContext(),
                            R.layout.user_list_item, names);
                    usersListView.setAdapter(namesArrayAdapter);

                    usersListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                        @Override
                        public void onItemClick(AdapterView<?> a, View v, int i, long l) {
                            openConversation(names, i);
                        }
                    });

                } else {
                    Toast.makeText(getApplicationContext(),
                        "Error loading user list",
                            Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    public void openConversation(ArrayList<String> names, int pos) {
        ParseQuery<ParseUser> query = ParseUser.getQuery();
        query.whereEqualTo("name", names.get(pos));
        query.findInBackground(new FindCallback<ParseUser>() {
           public void done(List<ParseUser> user, ParseException e) {
               if (e == null) {
                   Intent intent = new Intent(getApplicationContext(), MessagingActivity.class);
                   intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());
                   startActivity(intent);
               } else {
                   Toast.makeText(getApplicationContext(),
                       "Error finding that user",
                           Toast.LENGTH_SHORT).show();
               }
           }
        });
    }
}

Below is the instant messaging actvity

public class MessagingActivity extends Activity implements ServiceConnection, MessageClientListener {

    private String recipientId;
    private Button sendButton;
    private EditText messageBodyField;
    private String messageBody;
    private MessageService.MessageServiceInterface messageService;
    private MessageAdapter messageAdapter;
    private ListView messagesList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.messaging);

        doBind();

        messagesList = (ListView) findViewById(R.id.listMessages);
        messageAdapter = new MessageAdapter(this);
        messagesList.setAdapter(messageAdapter);

        Intent intent = getIntent();
        recipientId = intent.getStringExtra("RECIPIENT_ID");

        messageBodyField = (EditText) findViewById(R.id.messageBodyField);
        sendButton = (Button) findViewById(R.id.sendButton);

        sendButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                sendMessage();
            }
        });
    }

    private void sendMessage() {
        messageBody = messageBodyField.getText().toString();
        if (messageBody.isEmpty()) {
            Toast.makeText(this, "Please enter a message", Toast.LENGTH_LONG).show();
            return;
        }

        messageService.sendMessage(recipientId, messageBody);
        messageBodyField.setText("");
    }

    private void doBind() {
        Intent serviceIntent = new Intent(this, MessageService.class);
        bindService(serviceIntent, this, BIND_AUTO_CREATE);
    }

    @Override
    public void onDestroy() {
        unbindService(this);
        super.onDestroy();
    }

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        //Define the messaging service and add a listener
        messageService = (MessageService.MessageServiceInterface) iBinder;
        messageService.addMessageClientListener(this);
        if (!messageService.isSinchClientStarted()) {
            Toast.makeText(this, "The message client did not start."
                ,Toast.LENGTH_LONG).show();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        messageService = null;
    }

    @Override
    public void onMessageDelivered(MessageClient client, MessageDeliveryInfo deliveryInfo) {
        //Intentionally  left blank
    }

    @Override
    public void onMessageFailed(MessageClient client, Message message,
                                MessageFailureInfo failureInfo) {
        //Notify the user if message fails to send
        Toast.makeText(this, "Message failed to send.", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onIncomingMessage(MessageClient client, Message message) {
        messageAdapter.addMessage(message, MessageAdapter.DIRECTION_INCOMING);
    }

    @Override
    public void onMessageSent(MessageClient client, Message message, String recipientId) {
        messageAdapter.addMessage(message, MessageAdapter.DIRECTION_OUTGOING);
    }

    @Override
    public void onShouldSendPushData(MessageClient client, Message message, List<PushPair> pushPairs) {
        //Intentionally left blank
    }
}

My other issue is that it returns OjectID in the list, I would prefer if it were to return the "name", 'headline", and "age" column of the User class instead.

If you require additional information, let me know. Thanks in advance.

According to the cat log we can identify the source of the problem, line 90 in MatchingActivity.done .

08-07 16:49:44.810: E/AndroidRuntime(11444): at com.dooba.beta.MatchingActivity$3.done(MatchingActivity.java:90)

Your problem is in this method:

public void openConversation(ArrayList<String> names, int pos) {
    ParseQuery<ParseUser> query = ParseUser.getQuery();
    query.whereEqualTo("name", names.get(pos));
    query.findInBackground(new FindCallback<ParseUser>() {
       public void done(List<ParseUser> user, ParseException e) {
           if (e == null) {
               Intent intent = new Intent(getApplicationContext(), MessagingActivity.class);
               //Below is line 90:
               intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());
               startActivity(intent);
           } else {
               Toast.makeText(getApplicationContext(),
                   "Error finding that user",
                       Toast.LENGTH_SHORT).show();
           }
       }
    });
}

The source was a IndexOutOfBoundsException, accessing a index that does not exist. In line 90 we got the follow call:

intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());

Only in one place do we access a index in this line, here:

user.get(0).getObjectId()

We can thus assume that the list user is of size 0, when accessing a index in the list make sure that the user list is is big enough. Like this:

if(!user.isEmpty()){
     //the List user contains a user
     Intent intent = new Intent(getApplicationContext(), MessagingActivity.class);
     intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());
     startActivity(intent);
} else {
     //the List user is empty do what you wish.
}

Can you check userList's size? in the debugger? This is in your matchingActivity class

My guess is that it's an empty list and you are accessing the first element of an empty list

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM