2016-08-13 69 views
5

我正在制作一个机器人应用程序,用户可以在其中定义机器人稍后从设备中获取的打孔组合。为了允许用户存储这些培训,我定义了一个类“培训”,其中包含培训的ID,名称和冲床组合。此培训后来保存在一个数据库中,为此我写了一个DatabaseHandler类。添加和显示数据正常工作,但每当我想删除下述方法的条目:Nullpointer从SQL数据库中删除条目后出现异常

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

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

,并稍后尝试重新填充我的GridView(由GridAdapter类处理),我得到一个空指针例外

显示java.lang.NullPointerException:尝试从字段 'java.lang.String中com.noeth.tobi.mcrobektrainingsplaner.Training._name' 上读取空对象引用
在com.noeth.tobi。 mcrobektrainingsplaner.GridAdapter.getView(GridAdapter.java:50)

的GridAdapter的getView方法:

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

我计算过,它必须是与删除训练的ID,作为循环简单地遍历所有的ID,所以我写了一个方法recalcIDs其重新计算每个项目的删除训练后传来的ID:
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); 
     } 


    } 

} 

尽管如此,这并不修理它。
当重新安装应用程序并从一个全新的数据库开始时,所有东西都可以再次使用。
有没有人知道我做错了什么?

P.S:这里的getTraining方法在那里找不到名称:

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

首先从db中查询所有有效的ID,然后将它们映射到位置。 –

回答

2

我假设你的Training.setId方法不调用数据库。 你不应该改变你的训练ID,因为他们是由底层数据库管理的。如果您只更改应用程序逻辑中的ID,则两个数据集(应用程序和数据库)都会有所不同。 我建议在用户决定删除之后重新加载数据库中的所有培训,然后再调用Gridview.notifyDatasetChanged

+0

这是否意味着数据库本身具有每个项目的唯一ID?现在,由'DatabaseHandler.getTraining'调用并由'Training.setID'设置的ID是Training类中的一个变量。对不起,这样的一个nooby问题,但我没有定期的数据库工作。 –

+0

还有一个问题:你如何确定已经插入了多少次培训? – Jacob

+0

我这样做:http://pastebin.com/vdDWMz6Z –