Reputation: 15482
I cannot understand how am i initializing the DB wrong:
java.lang.NullPointerException
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188)
at com.example.stopcall.app.dal.PhoneDal.getItem(PhoneDal.java:105)
at com.example.stopcall.app.ItemDetailFragment$1.onClick(ItemDetailFragment.java:87)
at android.view.View.performClick(View.java:4654)
at android.view.View$PerformClick.run(View.java:19438)
at android.os.Handler.handleCallback(Handler.java:733)
the code falls on this line: SQLiteDatabase db = this.getWritableDatabase();
from this code:
public class PhoneDal extends SQLiteOpenHelper {
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = Constants.DB_NAME;
private static final String BLOCKED_PHONES_TABLE = "BLOCKED_PHONES_TABLE";
private static final String COMMENTS_TABLE = "COMMENTS_TABLE";
public PhoneDal(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// SQL statement to create book table
String CREATE_BLOCKED_PHONES_TABLE = "CREATE TABLE "
+ BLOCKED_PHONES_TABLE + " ( "
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, " + "phone TEXT, "
+ "isBlocked BIT )";
db.execSQL(CREATE_BLOCKED_PHONES_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (newVersion > oldVersion) {
Log.w("MyAppTag", "Updating database from version " + oldVersion
+ " to " + newVersion + " .Existing data will be lost.");
// Drop older books table if existed
db.execSQL("DROP TABLE IF EXISTS " + BLOCKED_PHONES_TABLE);
// create fresh books table
this.onCreate(db);
}
}
private static final String KEY_ID = "id";
private static final String KEY_PHONE = "KEY_PHONE";
private static final String KEY_IS_BLOCKED = "KEY_IS_BLOCKED";
public void addItem(Phone phone) {
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
initialization code:
public class ItemDetailFragment extends Fragment {
/**
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_ITEM_ID = "item_id";
/**
* The dummy content this fragment is presenting.
*/
private DummyContent.DummyItem mItem;
private PhoneDal phoneDal;
private CommentDal commentDal;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public ItemDetailFragment() {
this.mItem = mItem;
this.phoneDal = new PhoneDal(getActivity());
this.commentDal = new CommentDal(getActivity());
}
@SuppressLint("ValidFragment")
public ItemDetailFragment(DummyContent.DummyItem mItem, PhoneDal phoneDal, CommentDal commentDal) {
this.mItem = mItem;
this.phoneDal = phoneDal;
this.commentDal = commentDal;
}
Upvotes: 1
Views: 3531
Reputation: 16651
You are initializing PhoneDal with null as context, which causes the NPE later on. The problem is that you call getActivity()
in a constructor of your Fragment, at which point it will return null.
Don't implement a constructor for View components like Activities and Fragment!
Instead, use the dedicated methods like onCreate, OnStart, OnAttach to initialize and manipulate them.
This is also mentioned in the Javadoc of the constructor of Fragment:
Applications should generally not implement a constructor. The first place application code an run where the fragment is ready to be used is in onAttach(Activity), the point where the fragment is actually associated with its activity.
For more info on the Fragment lifecycle: Fragments
Incidentally, it is adviced to use the application context for initializing your SQLiteOpenHelper: Avoid memory leaks
Upvotes: 0
Reputation: 152827
public ItemDetailFragment() { this.phoneDal = new PhoneDal(getActivity());
Fragment constructor is too early to call getActivity()
- it will return null. Passing a null as Context
in SQLiteOpenHelper
constructor causes the exception when get...Database()
is invoked.
Postpone your PhoneDal
initialization to onAttach()
or later in the fragment lifecycle.
Upvotes: 3