2010-10-06 276 views
1

我剛開始爲Android開發。到目前爲止,這是令人驚訝的順利航行,但現在我遇到了實施SQLite數據庫的一些問題。我的代碼基於谷歌的記事本例子(它運行得非常好),但我不斷收到空指針異常,它似乎與getWritableDatabase()方法有關。Android SQLite數據庫空指針異常

的違規類是QuizDbAdapter:

package com.mypackage.myapp; 

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; 

public class QuizDbAdapter { 
    public static final String KEY_ROWID =   "_id"; 
    public static final String KEY_QUESTION =  "question"; 
    public static final String KEY_ANSWER1 =  "answer1"; 
    public static final String KEY_ANSWER2 =  "answer2"; 
    public static final String KEY_ANSWER3 =  "answer3"; 
    public static final String KEY_ANSWER4 =  "answer4"; 
    public static final String KEY_CORRECT_ANSWER = "correct_answer"; 
    public static final String KEY_IMAGE =   "image"; 
    public static final String KEY_CATEGORIES =  "categories"; 
    public static final String KEY_IMAGEQUESTION = "image_question"; 
    public static final String KEY_EXPLANATION = "explanation"; 

    private static final String TAG = "QuizDbAdapter"; 
    private DatabaseHelper databaseHelper; 
    private SQLiteDatabase database; 

    private static final String DATABASE_CREATE = 
     "create table questions (_id integer primary key autoincrement, " 
     + "question text not null, answer1 text not null, answer2 text not null," 
     + "answer3 text not null, answer4 text not null, correct_answer integer not null," 
     + "image text not null, categories text not null, image_question boolean not null," 
     + "explanation text not null);" 
     + "create table roadsigns (_id integer primary key autoincrement, " 
     + ");"; 

    private static final String DATABASE_NAME = "mydb.sqlite"; 
    private static final int DATABASE_VERSION = 1; 
    private static final String TABLE_QUESTIONS = "questions"; 

    private final Context context; 

    private static class DatabaseHelper extends SQLiteOpenHelper { 
     DatabaseHelper(Context c) { 
     super(c, DATABASE_NAME, null, DATABASE_VERSION); 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
     db.execSQL(DATABASE_CREATE); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
     db.execSQL("DROP TABLE IF EXISTS questions"); 
      onCreate(db); 
     } 
    } 

    public QuizDbAdapter(Context c) { 
     this.context = c; 
    } 

    public QuizDbAdapter open() throws SQLException { 
     databaseHelper = new DatabaseHelper(context); 
     database = databaseHelper.getWritableDatabase(); 
     return this; 
    } 

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

    public Cursor fetchAllQuestions() { 
     return database.query(TABLE_QUESTIONS, new String[] { KEY_ROWID, KEY_QUESTION, 
      KEY_ANSWER1, KEY_ANSWER2, KEY_ANSWER3, KEY_ANSWER4, KEY_CORRECT_ANSWER, 
      KEY_IMAGE, KEY_CATEGORIES, KEY_IMAGEQUESTION, KEY_EXPLANATION }, 
      null, null, null, null, null); 
    } 

    public Cursor fetchQuestion(long rowId) throws SQLException { 
     Cursor cursor = database.query(true, TABLE_QUESTIONS, new String[] { KEY_ROWID, 
      KEY_QUESTION, KEY_ANSWER1, KEY_ANSWER2, KEY_ANSWER3, KEY_ANSWER4, 
      KEY_CORRECT_ANSWER, KEY_IMAGE, KEY_CATEGORIES, KEY_IMAGEQUESTION, 
      KEY_EXPLANATION }, KEY_ROWID + "=" + rowId, null, null, null, null, null); 
     if (cursor != null) 
     cursor.moveToFirst(); 
     return cursor; 
    } 
} 

每當我嘗試使用

QuizDbHelper databaseHelper = new QuizDbHelper(this); 
databaseHelper.open(); // <-- X(

應用扼流圈和提供了一個空指針異常指示調用open(打開數據庫)。

堆棧跟蹤:

10-06 23:24:02.104: ERROR/AndroidRuntime(369): FATAL EXCEPTION: main 
10-06 23:24:02.104: ERROR/AndroidRuntime(369): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage.myapp/com.mypackage.myapp.QuestionActivity}: java.lang.NullPointerException 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread.access$2300(ActivityThread.java:125) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.os.Handler.dispatchMessage(Handler.java:99) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.os.Looper.loop(Looper.java:123) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at java.lang.reflect.Method.invokeNative(Native Method) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at java.lang.reflect.Method.invoke(Method.java:521) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at dalvik.system.NativeStart.main(Native Method) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369): Caused by: java.lang.NullPointerException 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at com.mypackage.myapp.Quiz.newQuiz(Quiz.java:88) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at com.mypackage.myapp.QuestionActivity.onCreate(QuestionActivity.java:21) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627) 
10-06 23:24:02.104: ERROR/AndroidRuntime(369):  ... 11 more 
+1

你有堆棧跟蹤? – EboMike 2010-10-06 20:31:31

+0

對不起,把堆棧跟蹤添加到原帖... – royen 2010-10-06 21:29:15

回答

1

Quiz.newQuiz一個靜態方法?如果是這種情況,this不可用(以及這樣的空指針)。

+1

不幸的不是。爲了好的衡量我記錄「這個」,它返回「[email protected]」這看起來像一個有效的內存地址給我。 – royen 2010-10-06 22:00:47

+1

忽視以上內容。那麼,結果是戳是對的。事後明顯地顯而易見。對於任何未來發現此問題的人:請確保將作爲上下文傳遞給SQliteOpenHelper的類實際上擴展了Activity。我的問題是Quiz是一個單例,它或多或少地忽略了「擴展活動」部分。 – royen 2010-10-06 22:20:52

0

確保數據庫被打開正確,你可以建立一些適配器類別,你可以調用它,只要你想

public SupplierAdapter open() throws SQLException { 
     dbHelper = new DatabaseHelper(context); 
     database = dbHelper.getWritableDatabase(); 
     return this; 
    }