2015-09-21 5 views
0

Я работаю над небольшим андроидным приложением, и я столкнулся с причудливой проблемой, которую я не могу решить. В устранении неполадок я сузил его с помощью этого небольшого тестового кода. Я получаю исключение NullPointerException для строки: String check = test.getName().Проблема с запросом базы данных SQLite SQLite

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

Поездка - это объект, который я создал с идентификатором и именем. trip - список массивов объектов Trip.

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(); 
    } 
}); 

В ArrayList поездки приходит из класса под названием DatabaseHandler, которая также имеет «getTrip()» метод, который вытягивает фактическую поездку из базы данных SQLite, это где я представляю себе, что проблема может это:

/** 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; 
} 

Очевидно, что я получаю исключение NullPointerException, потому что getTrip отправляет обратно null, что означает, что курсор возвращается пустым, и я не могу на всю жизнь выяснить, почему это может быть.

DatabaseHandler создает поездки 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; 
} 

То есть тот же ArrayList, который отображается в tripListView. Таким образом, нажатие на клик должно существовать, иначе вы не сможете щелкнуть по нему. Единственная другая возможность заключается в том, что getID возвращает неверный идентификатор, но с классом Trip этот простой я не вижу, как это возможно.

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

Я рву на себе волосы здесь, пытаясь понять это так, может быть, свежая пара глаз будет поймать его. Дайте мне знать, если вы видите что-нибудь здесь.

+0

Trip test = trip.get (clickedItemIndex); где метод trips.get() –

+0

Похоже, что вы получаете точный объект, который уже находится в списке ...? Пожалуйста, см. Мой обновленный ответ –

+0

trip.get (int) будет встроенным методом arraylist –

ответ

1

Эти линии являются нечетными:

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

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

Как правило арг были бы значения для запроса, так что я бы ожидать, чтобы увидеть это:

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

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

Я думаю, что запрос должен еще работайте так, как вы.


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? 
} 
+0

Я не понимаю, что странно, вы не можете использовать его для таблиц, но вы должны это сделать для всего остального. Моя проблема, казалось, не превращала id в String.Я нахожусь на других ошибках, так что спасибо за эту часть: -P Я извлекаю его там, потому что это тест (следовательно, имена переменных), очевидно, я не собираюсь оставлять этот код там. Проблема началась, когда я отправлял целое число из trip.get (clickedItemIndex) в качестве дополнительного в намерении другой деятельности. Цель показать вам тест - это точно указать, где эта проблема. –

0

Похоже, проблема была ид будучи Int, как это было своего рода предложено выше. Но я не могу заставить его работать с args вообще, что является неудачным, потому что я действительно хотел выяснить, как использовать эту функциональность. Во всяком случае, это единственный способ, которым это, кажется, работает:

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

Странная вещь, что с помощью параметра INT идентификатор в других методах отлично работает.

Смежные вопросы