2010-01-03 4 views
0

Je suis en train d'écrire une application Android pour Android, mais je reçois toujours une exception NullPointerException lorsque j'appelle ma classe DatabaseHelper. Le code qui semble être la cause de l'erreur est ci-dessous:Crashes de base de données Android NullPointerException

public Cursor GetAllRows() { 
     try { 
      return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_PHRASE}, 
        null, null, null, null, null); 
     } catch (SQLException e) { 
      Log.e("Exception on query", e.toString()); 
      return null; 
     } 
} 

Je suis allé à plusieurs reprises le code et voir aucune erreur, même si je manque normalement les choses faciles!

Quelqu'un peut-il voir quelque chose de mal? Si vous pensez que l'erreur existe en dehors de cela je peux poster plus de code mais je suis assez certain que c'est le bloc provoquant l'erreur ...

MISE À JOUR: Source complète de l'adaptateur DB. (Ceci est basé sur l'exemple du bloc-notes Si je me souviens bien).

package com.trapp.tts;

import android.content.ContentValues; import android.content.Context; importez android.database.Cursor; importez android.database.SQLException; importez android.database.sqlite.SQLiteDatabase; importez android.database.sqlite.SQLiteOpenHelper; import android.util.Log;

dbAdapter public class {

public static final String KEY_PHRASE = "phrase"; 

public static final String KEY_ROWID = "_id"; 

private static final String TAG = "DbAdapter"; 
private DatabaseHelper mDbHelper; 
private SQLiteDatabase mDb; 

/** 
* Database creation sql statement 
*/ 
private static final String DATABASE_CREATE = 
     "create table phrases (_id integer primary key autoincrement, " 
       + "phrase text not null);"; 

private static final String DATABASE_NAME = "db"; 
private static final String DATABASE_TABLE = " phrases"; 
private static final int DATABASE_VERSION = 1; 

private final Context mCtx; 

private static class DatabaseHelper extends SQLiteOpenHelper { 

    DatabaseHelper(Context context) { 
     super(context, DATABASE_NAME, null, DATABASE_VERSION); 
    } 

    @Override 
    public void onCreate(SQLiteDatabase db) { 

     db.execSQL(DATABASE_CREATE); 

     ContentValues cv=new ContentValues(); 

     cv.put(KEY_PHRASE, "1"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "2"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "3"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "4"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "5"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "6"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "7"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "8"); 
     db.insert("phrases", KEY_PHRASE, cv); 

     cv.put(KEY_PHRASE, "9"); 
     db.insert("phrases", KEY_PHRASE, cv); 
    } 

    @Override 
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     Log.w(TAG, "Upgrading database from version " + oldVersion + " to " 
       + newVersion + ", which will destroy all old data"); 
     db.execSQL("DROP TABLE IF EXISTS notes"); 
     onCreate(db); 
    } 
} 

/** 
* Constructor - takes the context to allow the database to be 
* opened/created 
* 
* @param ctx the Context within which to work 
*/ 
public DbAdapter(Context ctx) { 
    this.mCtx = ctx; 
} 

/** 
* Open the notes database. If it cannot be opened, try to create a new 
* instance of the database. If it cannot be created, throw an exception to 
* signal the failure 
* 
* @return this (self reference, allowing this to be chained in an 
*   initialization call) 
* @throws SQLException if the database could be neither opened or created 
*/ 
public DbAdapter open() throws SQLException { 
    mDbHelper = new DatabaseHelper(mCtx); 
    mDb = mDbHelper.getWritableDatabase(); 
    return this; 
} 

public void close() { 
    mDbHelper.close(); 
} 


/** 
* Create a new note using the title and body provided. If the note is 
* successfully created return the new rowId for that note, otherwise return 
* a -1 to indicate failure. 
* 
* @param title the title of the note 
* @param body the body of the note 
* @return rowId or -1 if failed 
*/ 
public long createPhrase(String title, String body) { 
    ContentValues initialValues = new ContentValues(); 
    initialValues.put(KEY_PHRASE, title); 


    return mDb.insert(DATABASE_TABLE, null, initialValues); 
} 

/** 
* Delete the note with the given rowId 
* 
* @param rowId id of note to delete 
* @return true if deleted, false otherwise 
*/ 
public boolean deletePhrase(long rowId) { 

    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; 
} 

/** 
* Return a Cursor over the list of all notes in the database 
* 
* @return Cursor over all notes 
*/ 
public Cursor fetchAllPhrases() { 

    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_PHRASE}, 
        null, null, null, null, null); 
} 

/** 
* Return a Cursor positioned at the note that matches the given rowId 
* 
* @param rowId id of note to retrieve 
* @return Cursor positioned to matching note, if found 
* @throws SQLException if note could not be found/retrieved 
*/ 
public Cursor fetchPhrase(long rowId) throws SQLException { 

    Cursor mCursor = 

      mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, 
        KEY_PHRASE}, KEY_ROWID + "=" + rowId, null, 
        null, null, null, null); 
    if (mCursor != null) { 
     mCursor.moveToFirst(); 
    } 
    return mCursor; 

} 

/** 
* Update the note using the details provided. The note to be updated is 
* specified using the rowId, and it is altered to use the title and body 
* values passed in 
* 
* @param rowId id of note to update 
* @param title value to set note title to 
* @param body value to set note body to 
* @return true if the note was successfully updated, false otherwise 
*/ 
public boolean updatePhrase(long rowId, String title, String body) { 
    ContentValues args = new ContentValues(); 
    args.put(KEY_PHRASE, title); 


    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; 
} 

}

appel code:

private void fillData() { 
    mCursor = dbHelper.fetchAllPhrases(); 
    startManagingCursor(mCursor); 
    ListAdapter adapter = new SimpleCursorAdapter(
      this, 
      android.R.layout.simple_list_item_1, 
      mCursor, 
      new String[] {"phrase"}, 
      new int[] {} 
      ); 
    setListAdapter(adapter); 


} 

Il semble planter sur l'appel à .fetchAllPhrases()

mCursor = dbHelper. fetchAllPhrases();

+0

Avez-vous essayé de définir un point d'arrêt et de débogage pour voir si 'db' est null? –

Répondre

1

1) vous n'êtes pas ouvrir le db, vous avez peut-être oublié d'appeler ouvert, quelque part

public DbAdapter(Context ctx) { 
    this.mCtx = ctx; 
    open(); 

}

2) vous n'êtes pas les valeurs en correspondance (et vous devez utiliser la même classe pour adaptateur)

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor, new String[] {"phrase"}, new int[] {android.R.id.text1}); 

3) vous devriez vérifier les erreurs

 cv.put(KEY_PHRASE, "1"); 
    if (db.insert("phrases", KEY_PHRASE, cv) == -1) { 
     Log.e(TAG, "error inserting"); 
    } 
1

Pouvez-vous donner la trace complète de la pile de l'erreur que vous obtenez?

La base de données est-elle initialisée?

Etes-vous peut-être obtenir une exception de référence nulle à partir du code qui appelle cela? (Ie. L'appelant est en supposant non NULL est renvoyée de ce?)

+0

Merci Jonathan et Eclipsed4utoo, J'ai fait un peu plus de débogage et il semble que l'erreur soit dans le code ci-dessus et que le curseur soit nul (je pense). J'ai mis à jour la question avec la source complète de mon adaptateur de DB, je devine que mon erreur est dedans. Merci encore! – Tom

Questions connexes