2010-01-03 100 views
0

我只是写了一个SQLite驱动的android应用程序,但是当我打电话给我的DatabaseHelper类时,我不断收到一个NullPointerException异常。看起来是导致错误的代码如下: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; 
     } 
} 

我已经遍地的代码,看到没有错误,虽然我通常会错过简单的东西!

任何人都可以看到错误?如果您认为错误存在于此之外,我可以发布更多代码,但是我相当确定这是导致错误的块...

更新:数据库适配器的完整源代码。 (这是基于记事本的例子,如果我没有记错的话)。

package com.trapp.tts;

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

公共类将对DBAdapter {

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

}

调用代码:

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


} 

这似乎崩溃的呼吁.fetchAllPhrases()

mCursor = dbHelper。 fetchAllPhrases();

+0

您是否尝试过设置断点并调试以查看'db'是否为空? – 2010-01-03 16:07:26

回答

1

1)你不打开数据库,你可能已经忘记了调用open,地方

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

}

2)你不映射值(和你应该使用适配器同一类)

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

3)您应检查错误

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

你可以从错误中得到完整的堆栈跟踪吗?

db是否初始化?

您是否可能从调用此代码的代码中获取空引用异常? (即是主叫方承担非空将从此被退回?)

+0

感谢Jonathan和Eclipsed4utoo, 我已经做了一些更多的调试,看起来错误在上面的代码中,并且游标为空(我认为)。 我已经更新了我的DB适配器的完整源代码的问题,我猜我的错误在于此。 再次感谢! – Tom 2010-01-03 19:15:19