2010-10-06 109 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; 
    }