2016-08-13 13 views
5

Pracuję nad aplikacją dla robota, w której użytkownik może zdefiniować kombinacje przebić, które robot pobierze później z urządzenia. Aby umożliwić użytkownikowi przechowywanie tych szkoleń, zdefiniowałem klasę "Treningi", która zawiera identyfikator, nazwę i kombinację treningu. Szkolenie to jest później zapisywane w bazie danych, do której napisałem klasę DatabaseHandler. Dodawanie i wyświetlanie danych działa poprawnie, ale kiedy chcę, aby usunąć wpis z poniższej metody:Wyjątek Nullpointer po usunięciu wpisu z bazy danych SQL

public void deleteTraining(Training training) { 
     SQLiteDatabase db = this.getWritableDatabase(); 

     db.delete(TABLE_TRAININGS, KEY_ID + " = ?", 
     new String[] { String.valueOf(training.getID()) }); 
     db.close(); 
} 

i później spróbować ponownie wypełnić mój GridView (obsługiwane przez klasę GridAdapter), otrzymuję NullPointer wyjątkiem

java.lang.NullPointerException: Próba odczytu z pola 'java.lang.String com.noeth.tobi.mcrobektrainingsplaner.Training._name' na null odniesienia obiektu
w com.noeth.tobi. mcrobektrainingsplaner.GridAdapter.getView (GridAdapter.java:50)

metoda getView z GridAdapter:

public View getView(int position, View convertView, ViewGroup parent) { 
    if (convertView == null) { 
     // if it's not recycled, initialize some attributes 
     btn = new Button(context); 
     btn.setLayoutParams(new GridView.LayoutParams(370, 350)); 
     btn.setPadding(2,100,2,100); 
     btn.setOnClickListener(new CustomOnClickListener(position, context)); 
     btn.setOnLongClickListener(new CustomOnLongClickListener(position, context, btn)); 

    } 
    else { 
     btn = (Button) convertView; 
    } 

    btn.setText(db.getTraining(position)._name); //Here the programm throws a Nullpointer Exception AFTER deleting an entry from the database 

    btn.setTextColor(Color.WHITE); 
    btn.setBackgroundResource(R.drawable.button_border); 
    btn.setTag("not_activated"); 
    btn.setId(position); 

    return btn; 
} 

Pomyślałem, że to musi mieć coś wspólnego z identyfikatorem usuniętego szkolenia, jak pętla po prostu przechodzi przez wszystkie identyfikatory więc napisałem metodę recalcIDs który przelicza id każdego elementu pochodzących po usuniętym szkolenia:
recalcIDs

public void recalcIDs(){ 
    int k = 1; 
    int subtract = 1; 
    int id; 
    Training training; 

    for(int i = deleted.get(0)+1; i < db.getTrainingCount(); i++){ 
     if(deleted.size() > 1){ 
      if(i < deleted.get(k)){ 
       training = db.getTraining(i); 
       id = training.getID(); 
       training.setID(id-subtract); 
      } 
      else{ 
       k+=1; 
       subtract+=1; 
      } 
     } 
     else{ 
      training = db.getTraining(i); 
      id = training.getID(); 
      training.setID(id-subtract); 
     } 


    } 

} 

jednak to nie napraw to.
Podczas ponownej instalacji aplikacji i rozpoczynając od zupełnie nowej bazy danych wszystko znowu działa.
Czy ktoś ma pojęcie, co zrobiłem źle?

P.S .: Oto metoda getTraining gdzie nie można znaleźć nazwy:

Training getTraining(int id) { 
    SQLiteDatabase db = this.getReadableDatabase(); 
    Training training; 
    Cursor cursor = db.query(TABLE_TRAININGS, new String[] { KEY_ID, 
        KEY_NAME, KEY_SK}, KEY_ID + "=?", 
      new String[] { String.valueOf(id) }, null, null, null, null); 
    if (cursor != null && cursor.moveToFirst()){ 

    training = new Training(Integer.parseInt(cursor.getString(0)), 
      cursor.getString(1), cursor.getLong(2)); 
     cursor.close(); 
    } 
    else{ 
     training = null; 
     Toast.makeText(con,"Couldn't find any training sessions!", Toast.LENGTH_LONG).show(); 
    } 

    // return training 
    return training; 
} 
+0

Najpierw sprawdź wszystkie ważne identyfikatory z db, a następnie zamapuj je na pozycje. –

Odpowiedz

2

Jestem zakładając swoją metodę Training.setId nie wywołać bazę danych. Nie powinieneś zmieniać identyfikatora treningu, ponieważ zarządza nim baza podkładania. Jeśli zmienisz tylko identyfikatory w twojej aplikacji logicznej, oba zestawy danych (aplikacja i baza danych) będą się różnić. Polecam przeładowanie wszystkich szkoleń z bazy danych po tym, jak użytkownik zdecydował się usunąć wszystkie szkolenia i zadzwonić później pod numer Gridview.notifyDatasetChanged.

+0

Czy to oznacza, że ​​tablice danych mają niepowtarzalny identyfikator dla każdego przedmiotu? W tej chwili identyfikator, do którego odwołuje się 'DatabaseHandler.getTraining' i jest ustawiony przez' Training.setID' jest zmienną wewnątrz klasy Training. Przepraszam za takie nieudane pytanie, ale nie pracuję regularnie z bazami danych. –

+0

Jeszcze jedno pytanie: jak ustalić, ile szkoleń zostało już włożonych? – Jacob

+0

Robię to tak: http://pastebin.com/vdDWMz6Z –

Powiązane problemy