I'm working on an app for a robot where the user can define punch combinations which the robot will later fetch from the device. To allow the user to store these trainings I have defined a class "Trainings" which holds the id, the name and the punch combination of the training. This training is later saved in a database, for which I have written a DatabaseHandler class. Adding and displaying the data works fine, but whenever I want to delete an entry with the method below:
public void deleteTraining(Training training) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_TRAININGS, KEY_ID + " = ?",
new String[] { String.valueOf(training.getID()) });
db.close();
}
and later try to populate my GridView again ( handled by a GridAdapter class), I get a Nullpointer Exception
java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.noeth.tobi.mcrobektrainingsplaner.Training._name' on a null object reference
at com.noeth.tobi.mcrobektrainingsplaner.GridAdapter.getView(GridAdapter.java:50)
the getView method of the 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;
}
I figured that it must have something to do with the id of the deleted training, as the loop simply goes through all ids so I wrote a method recalcIDs which recalculates the id of every item coming after the deleted training:
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);
}
}
}
However this does not fix it.
When reinstalling the app and starting with a completely new database everythings works again.
Does anybody have an idea what I've done wrong?
P.S.: Here's the getTraining method where it can't find the name:
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;
}
I'm assuming your the Training.setId
method doesn't call the database.
You shouldn't change the id of your training because they get managed by the underlaying database. If you only change the ids in you application logic both datasets (application and database) will differ.
I would recommend to reload all the trainings from the database after a user decided to delete one and call the Gridview.notifyDatasetChanged
afterwards.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With