首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >getWritableDatabase抛出NullPointerException

getWritableDatabase抛出NullPointerException
EN

Stack Overflow用户
提问于 2014-05-28 00:10:35
回答 3查看 2K关注 0票数 0

我已经搜索了现有的NPE/数据库线程,但没有找到任何直接相关的东西……

我有一个OnClickListener类(独立于关联的Activity类),它调用下面代码中的createFromPreset方法。下面方法代码的最后一行(this.getWritableDatabase)抛出了一个NPE。当我调试代码并在该行中断时,"this“显示为"TableControllerMealItem”(不是我所期望的null )。

这段代码以前工作得很好。这可能是巧合,但我刚刚创建了一个Application类(并在Android Manifest中注册了它)。这会不会影响到什么呢??

代码语言:javascript
复制
public class TableControllerMealItem extends MySQLiteHelper {
    public TableControllerMealItem(Context context) {
        super(context);
    }
public long createFromPreset(meal_item meal_item, long meal_id, long preset_item_id) {
        String presetDesc = "";
        int presetMinutes = 0;

        //Get details from the preset_item (description and minutes)
        String sql = "SELECT * FROM preset_item WHERE _id = " + preset_item_id;
        SQLiteDatabase db = this.getWritableDatabase();

下面是LogCat:

代码语言:javascript
复制
05-27 11:58:39.613: E/AndroidRuntime(3021): java.lang.NullPointerException
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at com.ian.mealtimer.TableControllerMealItem.createFromPreset(TableControllerMealItem.java:56)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at com.ian.mealtimer.OnClickListenerSelectPresetItem.onClick(OnClickListenerSelectPresetItem.java:40)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.view.View.performClick(View.java:4438)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.view.View$PerformClick.run(View.java:18422)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.os.Handler.handleCallback(Handler.java:733)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.os.Handler.dispatchMessage(Handler.java:95)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.os.Looper.loop(Looper.java:136)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at android.app.ActivityThread.main(ActivityThread.java:5017)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at java.lang.reflect.Method.invokeNative(Native Method)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at java.lang.reflect.Method.invoke(Method.java:515)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
05-27 11:58:39.613: E/AndroidRuntime(3021):     at dalvik.system.NativeStart.main(Native Method)

MySQLite帮助器类如下所示:

代码语言:javascript
复制
public class MySQLiteHelper extends SQLiteOpenHelper {
    private static final String TAG = "MySQLiteHelper";
    public static final String TABLE_PRESET_ITEM = "preset_item";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_PRESET_DESC = "preset_desc";
    public static final String COLUMN_PRESET_MINUTES = "preset_minutes";
    protected static final String DATABASE_NAME = "mealtimersqlite.db";
    private static final int DATABASE_VERSION = 1;

    public MySQLiteHelper(Context context) {
        super(context, "mealtimersqlite.db", null, 5);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        String SQLCommand;

        SQLCommand = "CREATE TABLE preset_item( _id INTEGER PRIMARY KEY, "
                + "preset_desc TEXT NULL, preset_minutes INTEGER NULL );";
        db.execSQL(SQLCommand);

        SQLCommand = "CREATE TABLE meal(_id INTEGER PRIMARY KEY,"
                + "meal_desc TEXT NULL, meal_ready_time INTEGER NULL, meal_reminders_flag INTEGER NULL);";
        db.execSQL(SQLCommand);

        SQLCommand = "CREATE TABLE meal_item(_id INTEGER PRIMARY KEY, "
                + "meal_item_desc TEXT NULL, meal_item_minutes INTEGER NULL, meal_item_start_time INTEGER NULL, "
                + "meal_item_ready_time INTEGER NULL, fk_meal_id INTEGER NOT NULL, fk_preset_item_id INTEGER NULL );";
        db.execSQL(SQLCommand);
        Log.d(TAG, "Mealtimer Database Created");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
        // TODO Auto-generated method stub
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS preset_item;");
        db.execSQL("DROP TABLE IF EXISTS meal;");
        db.execSQL("DROP TABLE IF EXISTS meal_item;");
        Log.d(TAG, "Mealtimer Database Tables Dropped;");
        // Create tables again
        onCreate(db);
    }

}

下面是调用createFromPreset方法的类:

代码语言:javascript
复制
public class OnClickListenerSelectPresetItem implements OnClickListener {
    public final static String EXTRA_MEAL_ID = "com.ian.mealtimer.MEAL_ID";
    private long glbMealId = 1;
    Context context;
    private Activity activity;

    public OnClickListenerSelectPresetItem(Activity activity){
        this.activity = activity;
        this.glbMealId = ((MealTimerApplication) activity.getApplication()).getMealId();
        }
    public void onCreate(long meal_id) {
    }

    public void onClick(View view) {
        //INSERT a meal_item using then preset_item_id of clicked item
        //then return to the MealItemDetail Activity

        //First get the id of the selected item
        Long selectedPresetItem = Long.valueOf(view.getTag().toString());

        //Now insert the meal_item record

        // Save new meal_item record
        meal_item meal_item = new meal_item();
        long newRecord = new TableControllerMealItem(
                context).createFromPreset(meal_item, glbMealId, selectedPresetItem);
EN

回答 3

Stack Overflow用户

发布于 2014-05-28 00:40:51

传递给SQLiteOpenHelper构造函数的Contextnull

票数 2
EN

Stack Overflow用户

发布于 2014-05-28 01:36:56

OnClickListenerSelectPresetItem中的context成员变量永远不会初始化,它的默认值为null

Contextnull传递给SQLiteOpenHelper构造函数会导致getDatabaseLocked()中的NPE,例如在帮助器上调用getWritableDatabase()

票数 0
EN

Stack Overflow用户

发布于 2014-05-28 01:46:18

您需要通过传递给OnClickListenerSelectPresetItem()Activity参数初始化本地成员Context

代码语言:javascript
复制
public OnClickListenerSelectPresetItem(Activity activity) {
  this.activity = activity;
  this.context = activity;  // Activity is derived from Context
  this.glbMealId = ((MealTimerApplication) activity.getApplication()).getMealId();
}

这是因为Activity is dervied from (a subclass of) Context

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23894155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档