Reputation: 597
I've trawled through existing NPE/database threads but couldn't find anything directly relevant...
I have an OnClickListener class (separate from the associated Activity class) which calls the createFromPreset method in the code below. The last line in the method code below (this.getWritableDatabase) throws a NPE . When I debug the code and break at that line "this" is showing as "TableControllerMealItem" (not null as I was expecting).
This code was previously working fine. It could be a coincidence, but I just created an Application class (and registed it in the Android Manifest). Could this be messing with anything??
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();
Here's the LogCat:
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)
The MySQLite helper class is here:
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);
}
}
Here's the class that calls the createFromPreset method:
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);
Upvotes: 0
Views: 2115
Reputation: 8236
You need to initialize the local member Context
from the Activity
argument passed in to OnClickListenerSelectPresetItem()
:
public OnClickListenerSelectPresetItem(Activity activity) {
this.activity = activity;
this.context = activity; // Activity is derived from Context
this.glbMealId = ((MealTimerApplication) activity.getApplication()).getMealId();
}
This works because Activity
is dervied from (a subclass of) Context
.
Upvotes: 0
Reputation: 152817
The context
member variable in your OnClickListenerSelectPresetItem
is never initialized and it has the default value null
.
Passing a null
for a Context
to SQLiteOpenHelper
constructor leads to the NPE in getDatabaseLocked()
once e.g. getWritableDatabase()
is called on the helper.
Upvotes: 0
Reputation: 10274
The Context
that you are passing to the SQLiteOpenHelper
constructor is null
.
Upvotes: 2