0

I've been working on a little android app and I've run into a bizarre problem that I can't work out. In troubleshooting I narrowed it down with this little bit of test code. I'm getting a NullPointerException for the line: String check = test.getName().

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.******.triptracker.Trip.getName()' on a null object reference

Trip is an object I created with an id and a name. trips is an array list of Trip objects.

tripListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        clickedItemIndex = position;
        Trip test = trips.get(clickedItemIndex);
        int testID = test.getID();
        test = dbHandler.getTrip(testID);
        String check = test.getName();
    }
});

The arraylist trips comes from a class called DatabaseHandler which also has the "getTrip()" method which pulls the actual trip from the SQLite database, this is the where I imagine the problem could is:

/** PURPOSE: Return trip from database with given ID **/
public Trip getTrip(int id)
{
    SQLiteDatabase db = getReadableDatabase();
    Trip trip = null;
    String[] args = new String[] { KEY_TRIP_ID };

    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_TRIPS + " WHERE ? = " + id, args);

    if (cursor.moveToFirst())
    {
        trip = new Trip(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3));
    }
    cursor.close();
    db.close();
    return trip;
}

Obviously I'm getting the NullPointerException because getTrip is sending back null which means the cursor is coming back empty and I can't for the life of me figure out why that might be.

DatabaseHandler creates the trips arraylist:

/** PURPOSE: Fetch all trips in database
 RETURNS: List of all trips **/
public List<Trip> getAllTrips()
{
    SQLiteDatabase db = getWritableDatabase();
    List<Trip> trips = new ArrayList<Trip>();
    Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_TRIPS, null);

    if (cursor.moveToFirst())
    {
        do {
            trips.add(new Trip(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)));
        }
        while (cursor.moveToNext());
    }
    cursor.close();
    db.close();
    return trips;
}

That is the same arraylist which is displayed in tripListView. So the trip being clicked on must exist otherwise you wouldn't be able to click on it. The only other possibility then is that the getID is returning the wrong id but with a Trip class this simple I can't see how that's possible either.

public class Trip {

    private int id;
    private String name, startDate, endDate;

    public Trip(int id, String name, String startDate, String endDate)
    {
        this.id = id;
        this.name = name;
        this.startDate = startDate;
        this.endDate = endDate;
    }

    // Accessors
    public int getID() { return id; }

    public String getName() { return name; }
}

I'm tearing my hair out here trying to figure this out so maybe a fresh pair of eyes will catch it. Let me know if you see anything here.

3
  • Trip test = trips.get(clickedItemIndex); where is the trips.get() method Commented Sep 21, 2015 at 1:15
  • It looks as though you are retrieving the exact object that is already in the list... ? Please see my updated answer Commented Sep 21, 2015 at 1:29
  • trips.get(int) would be a built in arraylist method Commented Sep 21, 2015 at 1:40

2 Answers 2

1

These lines are odd:

String[] args = new String[] { KEY_TRIP_ID };

Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_TRIPS + " WHERE ? = " + id, args);

Typically the args would be the values for the query, so I would expect to see this:

String[] args = new String[] { Integer.toString(id) };

Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_TRIPS + " WHERE " + KEY_TRIP_ID + " = ?", args);

I think the query should still work the way you have it, though.


EDIT:

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    clickedItemIndex = position;
    Trip test = trips.get(clickedItemIndex);  // so if you have the Trip here...
    int testID = test.getID();
    test = dbHandler.getTrip(testID);         // why are you retrieving it here?
    String check = test.getName();            // shouldn't they be exactly the same?
}
Sign up to request clarification or add additional context in comments.

1 Comment

I don't see what's odd about it, you can't use it for tables but you should for everything else. My problem appeared to be not converting the id to a String. I'm on to other bugs, so thank you for that part :-P I'm retrieving it there because this is a test (hence the variable names) obviously I'm not actually going to leave that code in there. The issue started when I was sending the integer from trips.get(clickedItemIndex) as an extra in an intent to another activity. The point of showing you the test is to prove exactly where the problem is occurring.
0

It seems like the problem was the id being an int, as was sort of suggested above. But I can't get it to work with the args at all, which is unfortunate because I really wanted to figure out how to make use of that functionality. Anyway this is the only way it seems to work:

Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_TRIPS + " WHERE " + KEY_TRIP_ID + " = " + Integer.toString(id), null);

The weird thing is that using the parameter int id in other methods works perfectly fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.