Using Singleton pattern for Sqlite database in Android - java

I am a little confused how to do this properly. Here is my DatabaseHelper class:
public class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper mInstance = null;
private static final String DB_NAME = "database.db";
private static final int DB_VERSION = 1;
private Context mContext;
public static DatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
...
Assuming this is right, is this the correct way to handle the querying class:
public class DatabaseProcessor {
private SQLiteDatabase mDatabase;
private DatabaseHelper mSQLHelper;
private Context mContext;
public DatabaseProcessor(Context context) {
mContext = context;
mSQLHelper = new DatabaseHelper(mContext);
}
private void open() throws SQLException {
mDatabase = mSQLHelper.getWritableDatabase();
}
private void close() {
mDatabase.close();
}
public void insertSomethingIntoDb(String key) {
ContentValues values = new ContentValues();
values.put("some_column_name", name);
open();
mDatabase.insert("some_table_name", null, values);
close();
}
...
And if this is right, how do I properly invoke a db method from somewhere else in the code such as an Activity, Fragment, etc, anywhere.

You should make the DatabaseHelper constructor private and create instances of this class by using the getInstance method. eg: mSQLHelper = DatamabseHelper.getInstance(context).
To call a method of this class, you can do something like this.
DatabaseHelper.getInstance(context).someFunction(...);
And to use any of the DatabaseProcessor functions, you can do this:
new DatabaseProcessor(context).insertSomethingIntoDb(...);
Keep in mind that this singleton approach has some problems, for starters, it doesn't support multithreading, there is no mechanism in place to assure that if two threads ask for an instance at the same time, only one instance will be created.

Related

Static database connection SQLite

I would like to ask anyone to please help me to modify my database connection code. What I have now is it's a part of one of my method class and it will make a connection every time I call it ( which I know its very inefficient). But when I try to move the connection part out from the method it breaks the code. I just wonder if I could make a static class somewhere so I can reuse it in other method as well.
Thanks so much for any help in advance, it is really appreciated.
Here is the method code:
public void getListDetail(){
//listDetailData.clear();
ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
final SQLiteDatabase db = databaseConnection.open();
final ArrayList<ShoppingItem> lists = ShoppingListItemTable.selectAllItems(db, selectedID);
databaseConnection.close();
//create a list adapter and set adapter
ShoppingListItemAdapter adapter = new ShoppingListItemAdapter(this, R.layout.activity_item_detail_list, lists);
ListView_ListDetail = findViewById(R.id.ListView_ListDetail);
ListView_ListDetail.setAdapter(adapter);
adapter.notifyDataSetChanged();
// ((ArrayAdapter<String>)ListView_ListDetail.getAdapter()).notifyDataSetChanged();
}
Database class:
package com.puyakul.prin.psychic_shopping;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.provider.ContactsContract;
import android.util.Log;
public class ShoppingListDatabase {
private static final String TAG = "ShoppingListDatabase";
private static final String DATABASE_NAME = "ShoppingListDatabase";
private static final int DATABASE_VERSION = 3;
private SQLiteDatabase mDb;
private DatabaseHelper mDbHealper;
private final Context mCtx;
public ShoppingListDatabase(Context ctx){
this.mCtx = ctx;
}
/**
* DatabaseHelper class.
*
* Database helper class to manage connections with the database.
*/
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "DatabaseHelper onCreate");
db.execSQL(ShoppingListItemTable.CREATE_STATEMENT);
db.execSQL(ShoppingListTable.CREATE_STATEMENT);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "DatabaseHelper onUpgrade");
db.execSQL("DROP TABLE IF EXISTS " + ShoppingListItemTable.TABLE_NAME);
db.execSQL("DROP TABLE IF EXISTS " + ShoppingListTable.TABLE_NAME);
onCreate(db); //this will recreate the database as if it were new
}
}
public SQLiteDatabase open(){
mDbHealper = new DatabaseHelper(mCtx);
mDb = mDbHealper.getReadableDatabase();
return mDb;
}
public void close(){
mDb = null;
}
}
I have tried to declare variables within onCreate so I can use with other methods in the class like this
//================DATABASE CONNECTION=====================//
private ShoppingListDatabase databaseConnection;
private SQLiteDatabase db = databaseConnection.open();
private String selectedList;
private int selectedID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
setContentView(R.layout.activity_main_lists_detail);
ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
SQLiteDatabase db = databaseConnection.open();
lists = ShoppingListItemTable.selectAllItems(db, selectedID);
and this is the error
Process: com.puyakul.prin.psychic_shopping, PID: 5635
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.puyakul.prin.psychic_shopping/com.puyakul.prin.psychic_shopping.MainListsDetail}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.puyakul.prin.psychic_shopping.ShoppingListDatabase.open()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2548)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase com.puyakul.prin.psychic_shopping.ShoppingListDatabase.open()' on a null object reference
at com.puyakul.prin.psychic_shopping.MainListsDetail.<init>(MainListsDetail.java:46)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1078)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2538)
Opening and closing the connection can be inefficient/costly so perhaps introduce/use the following :-
public SQLiteDatabase open(){
if (mDb == null) {
mDbHealper = new DatabaseHelper(mCtx);
mDb = mDbHealper.getReadableDatabase();
}
return mDb;
}
or alternately :-
public synchronized SQLiteDatabase open(){
if (mDb == null) {
mDbHealper = new DatabaseHelper(mCtx);
mDb = mDbHealper.getReadableDatabase();
}
return mDb;
}
and never call the close, except when the main activity is being destroyed. Then you will retrieve the one connection.
Here's some example uses based upon your ShoppingListDatabase class.
First a modified class with a few extra methods inside (addShoppingList, getAllShoppingListsAsCursor and logDBTables) and just a very simple shoppinglist table :-
public class ShoppingListDatabase {
private static final String TAG = "ShoppingListDatabase";
private static final String DATABASE_NAME = "ShoppingListDatabase";
private static final int DATABASE_VERSION = 3;
private static final String TBNAME = "shoppinglist";
public static final String COL_SHOPPINGLIST_NAME = "shoppinglist_name";
private SQLiteDatabase mDb;
private DatabaseHelper mDbHealper;
private final Context mCtx;
public ShoppingListDatabase(Context ctx){
this.mCtx = ctx;
}
/**
* DatabaseHelper class.
*
* Database helper class to manage connections with the database.
*/
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context){
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "DatabaseHelper onCreate");
//db.execSQL(ShoppingListItemTable.CREATE_STATEMENT);
//db.execSQL(ShoppingListTable.CREATE_STATEMENT);
String crtsql = "CREATE TABLE If NOT EXISTS " + TBNAME + "(" +
COL_SHOPPINGLIST_NAME + " TEXT " +
")";
db.execSQL(crtsql);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "DatabaseHelper onUpgrade");
//db.execSQL("DROP TABLE IF EXISTS " + ShoppingListItemTable.TABLE_NAME);
//db.execSQL("DROP TABLE IF EXISTS " + ShoppingListTable.TABLE_NAME);
onCreate(db); //this will recreate the database as if it were new
}
}
public synchronized SQLiteDatabase open(){
if (mDb == null) {
mDbHealper = new DatabaseHelper(mCtx);
mDb = mDbHealper.getReadableDatabase();
}
return mDb;
}
public void close(){
mDb = null;
}
public long addShoppingList(String name) {
ContentValues cv = new ContentValues();
cv.put(COL_SHOPPINGLIST_NAME,name);
return mDb.insert(TBNAME,null,cv);
}
public Cursor getAllShoppingListAsCursor() {
return mDb.query(TBNAME,
null,
null,
null,
null,null,
null
);
}
public void logDBTables() {
Cursor csr = mDb.query("sqlite_master",null,null,null,null,null,null);
while (csr.moveToNext()) {
Log.d(TAG,"Item " +
csr.getString(csr.getColumnIndex("name")) +
" was created using " +
csr.getString(csr.getColumnIndex("sql"))
);
}
}
}
Here's code from an Activity (that uses the Database connection in various ways) :-
public class MainActivity extends AppCompatActivity {
ShoppingListDatabase mSL;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSL = new ShoppingListDatabase(this);
mSL.open();
SO50312618();
SO50312618_other();
Cursor csr = mSL.getAllShoppingListAsCursor();
while(csr.moveToNext()) {
Log.d("SL INFO","Shopping List " + String.valueOf(csr.getPosition() + 1) +
" is " +
csr.getString(csr.getColumnIndex(ShoppingListDatabase.COL_SHOPPINGLIST_NAME))
);
}
}
private void SO50312618() {
ShoppingListDatabase databaseConnection = new ShoppingListDatabase(this);
SQLiteDatabase db = databaseConnection.open();
databaseConnection.logDBTables();
}
private void SO50312618_other() {
mSL.addShoppingList("List001");
mSL.addShoppingList("List002");
}
}
The results being :-
05-13 05:36:24.290 4245-4245/soanswers.soanswers D/ShoppingListDatabase: Item android_metadata was created using CREATE TABLE android_metadata (locale TEXT)
Item shoppinglist was created using CREATE TABLE shoppinglist(shoppinglist_name TEXT )
05-13 05:36:24.302 4245-4245/soanswers.soanswers D/SLĀ INFO: Shopping List 1 is List001
Shopping List 2 is List002
All the various uses will use the same single connection.

Error when accessing a SQlite database in android studio

Following my last post i was using SQLiteOpenHelper to access a pre-populated sqlite database and someone suggested i use SQLAssetHelper so i found a guide followed it and tried to implement it but i am still getting errors.
like: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.File android.content.Context.getDatabasePath(java.lang.String)' on a null object reference
I know what a null pointer exception is in most cases but dont understand it in this context as i am new to android development. The errors on line 26 of my DBHleper class below. - String dbPath = myContext.getDatabasePath(DATABASE_NAME).getPath();
public class DBHelper extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "Database.db";
private static final int DATABASE_VERSION = 1;
private Context myContext;
private SQLiteDatabase mDatabase;
public DBHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
public void openDatabase(){
String dbPath = myContext.getDatabasePath(DATABASE_NAME).getPath();
if(mDatabase!= null && mDatabase.isOpen()){
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath,null,SQLiteDatabase.OPEN_READWRITE);
}
public Cursor getItems(){
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables("Attraction");
Cursor c = qb.query(db,null,null,null,null,null,null);
c.moveToFirst();
return c;
}
}
My main
public class MainActivity extends AppCompatActivity {
DBHelper newDB;
private Cursor attraction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
newDB = new DBHelper(this);
newDB.openDatabase();
attraction = newDB.getItems();
}
}
I am probably having a mental block and not seeing the solution but any more help on this issue will be appreciated.

How do I properly execute database calls on other threads?

I am really confused how I should be using threads in my Android applications for database interaction. There are too many resources and I don't know which to choose from. So I'm hoping to get more specific and focused advice on my particular situation so I have a starting point.
This is my database class structure, which works great so far:
public class DatabaseHelper extends SQLiteOpenHelper {
private static volatile SQLiteDatabase mDatabase;
private static DatabaseHelper mInstance = null;
private static Context mContext;
private static final String DB_NAME = "database.db";
private static final int DB_VERSION = 1;
private static final DB_CREATE_THINGY_TABLE = "CREATE TABLE blahblahblah...";
//other various fields here, omitted
public static synchronized DatabaseHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
try {
mInstance.open();
}
catch (SQLException e) {
e.printStackTrace();
}
}
return mInstance;
}
private DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE_THINGY_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
#Override
public void onConfigure(SQLiteDatabase db){
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}
public void open() throws SQLException {
mDatabase = getWritableDatabase();
}
public void close() {
mDatabase.close();
}
public long addNewThingy(String name) {
ContentValues values = new ContentValues();
values.put(DatabaseHelper.THINGY_COLUMN_NAME, name);
return mDatabase.insertWithOnConflict(DatabaseHelper.THINGY_TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
}
public Thingy getThingyById(long id) {
Cursor cursor = mDatabase.query(
DatabaseHelper.THINGY_TABLE, // table
new String[]{DatabaseHelper.THINGY_COLUMN_ID, DatabaseHelper.THINGY_COLUMN_NAME}, // column names
DatabaseHelper.THINGY_COLUMN_ID + " = ?", // where clause
new String[]{id + ""}, // where params
null, // groupby
null, // having
null); // orderby
cursor.moveToFirst();
Thingy thingy = null;
if (!cursor.isAfterLast()) {
String name = getStringFromColumnName(cursor, DatabaseHelper.THINGY_COLUMN_NAME);
thingy = new Thingy(id, name);
cursor.moveToNext();
}
cursor.close();
return thingy;
}
}
So any time I want access to the database I do mDatabaseHelper = DatabaseHelper.getInstance(context); and I am good to go. I don't make any explicit calls to open() or close() or anything like that. However right now I am making all my database calls on the UI thread, I believe (either in my onCreate or onCreateView methods or separate methods which don't invoke any new threads or anything).
How would I correctly make this threaded so that I am not performing database operations on the UI thread?
I figure I have to change all my database calls to basically do this:
Make any necessary edits to my database class first to ensure it will work properly in the event that multiple threads are trying to perform operations at the same time. I already tried by making my class a singleton (I think it's a singleton, anyway?) and using keywords like "volatile" and "synchronized" but maybe I am missing something somewhere.
Perform database operation in its own thread.
Somehow trigger additional code back in the appropriate function/activity/fragment that will execute once the database operation has completed.
Make this whole process versatile enough to where I can do it anywhere.
Am I making sense? Is this the right way to be going about all this? Is there a simple example you can make that can show me how to, for example, correctly do something like mThingy = mDatabaseHelper.getThingyById(id); or mDatabaseHelper.addNewThingy(someName); from a sample activity/fragment/etc using proper threading?
Simple solution using Threads
public class DatabaseHelper extends SQLiteOpenHelper {
//...
public void addNewThingyAsync(final String name, final Callback<Long> cb) {
new Thread(new Runnable(){
#Override
public void run(){
cb.callback(addNewThingy(name));
}
}).start();
}
private synchronized long addNewThingy(String name){
//implementation...
}
public void getThingyByIdAsync(final long id, final Callback<Thingy> cb) {
new Thread(new Runnable(){
#Override
public void run(){
cb.callback(getThingyById(id));
}
}).start();
}
private synchronized Thingy getThingyById(long id) {
//implementation...
}
public interface Callback<T> {
public void callback(T t);
}
}
Solution using AsyncTasks
Same as above with the following changes:
public class DatabaseHelper extends SQLiteOpenHelper {
//...
public void addNewThingyAsync(final String name, final Callback<Long> cb) {
new AsyncTask<Void, Void, Long>(){
#Override
protected Long doInBackground(Void... ignoredParams) {
return addNewThingy(name);
}
#Override
protected void onPostExecute(Long result) {
cb.callback(result);
}
}.execute();
}
//...
public void getThingyByIdAsync(final long id, final Callback<Thingy> cb) {
new AsyncTask<Void, Void, Thingy>(){
#Override
protected Thingy doInBackground(Void... ignoredParams) {
return getThingyById(id);
}
#Override
protected void onPostExecute(Thingy result) {
cb.callback(result);
}
}.execute();
}
//...
}
Calling (works with both approaches)
long mId = ...;
mDatabaseHelper = DatabaseHelper.getInstance(context);
mDatabaseHelper.getThingyByIdAsync(mId, new Callback<Thingy>{
#Override
public void callback(Thingy thingy){
//do whatever you want to do with thingy
}
});
How would I correctly make this threaded so that I am not performing
database operations on the UI thread?
Simply perform any database operations off the UI thread. A common technique involves an AsyncTask. For example:
public class GetThingyTask extends AsyncTask<Long, Void, Thingy> {
private Context context;
public AddTask(Context context){
this.context = context;
}
#Override
protected Thingy doInBackground(Long... ids) {
final long id = ids[0];
Cursor cursor = DatabaseHelper.getInstance(context).query(
DatabaseHelper.THINGY_TABLE,
new String[]{
DatabaseHelper.THINGY_COLUMN_ID,
DatabaseHelper.THINGY_COLUMN_NAME
},
DatabaseHelper.THINGY_COLUMN_ID + "=?",
new String[]{String.valueOf(id)},
null, null, null);
String name = null;
if (cursor.moveToFirst() && (cursor.getCount() > 0)) {
name = getStringFromColumnName(cursor, DatabaseHelper.THINGY_COLUMN_NAME);
}
cursor.close();
return new Thingy(id, name);
}
#Override
protected void onPostExecute(Thingy thingy) {
//Broadcast the Thingy somehow. EventBus is a good choice.
}
}
And to use it (inside, for example, an Activity):
new GetThingyTask(this).execute(id);

Correct way to open/close the database?

Right now I am using a static instance of the SQLOpenHelper class like so:
public class DatabaseHelper extends SQLiteOpenHelper {
private static DatabaseHelper mInstance = null;
private final Context mContext;
//...
public static synchronized DatabaseHelper getInstance(Context context) {
/**
* use the application context as suggested by CommonsWare.
* this will ensure that you don't accidentally leak an Activity's
* context (see this article for more information:
* http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
*/
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
private DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
//...
}
And then a DatabaseProcessor class like so:
public class DatabaseProcessor {
private SQLiteDatabase mDatabase;
private DatabaseHelper mSQLHelper;
private Context mContext;
public DatabaseProcessor(Context context) {
mContext = context;
mSQLHelper = DatabaseHelper.getInstance(mContext);
}
public void open() throws SQLException {
mDatabase = mSQLHelper.getWritableDatabase();
}
public void close() {
mDatabase.close();
}
//...
}
So if I want to access my database, I do something like this:
DatabaseProcessor mDatabaseProcessor = new DatabaseProcessor(this);
mDatabaseProcessor.open();
mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults();
mDatabaseProcessor.close();
Is this the correct way to do this? Or is it better to open the database in the base Activity onResume() method and close it during onPause()? How do I correctly throw errors for situations where the database is not open when I try to run a query?
EDIT Refactored version:
public class DatabaseHelper extends SQLiteOpenHelper {
private static SQLiteDatabase mDatabase;
private static DatabaseHelper mInstance = null;
private static Context mContext;
// ...
public static synchronized DatabaseHelper getInstance(Context context) {
/**
* use the application context as suggested by CommonsWare.
* this will ensure that you don't accidentally leak an Activity's
* context (see this article for more information:
* http://android-developers.blogspot.nl/2009/01/avoiding-memory-leaks.html)
*/
if (mInstance == null) {
mInstance = new DatabaseHelper(context.getApplicationContext());
}
return mInstance;
}
private DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
mContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DB_CREATE_SOME_TABLE); //some SQL expression
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DB_ALTER);
}
public void open() throws SQLException {
mDatabase = getWritableDatabase();
}
public void close() {
mDatabase.close();
}
public boolean isOpen() {
return mDatabase.isOpen();
}
//below this would be various CRUD functions operating on mDatabase
// ...
// ...
}
The best way would be to put your query/transaction statements in try-catch and then release all your resources and close the connection in finally block.
try{
mSomeList = mDatabaseProcessor.doSomeQueryAndReturnResults();
} catch(Exception exc){
//Catch exceptions here
}
finally{
if(mDatabaseProcessor != null)
mDatabaseProcessor.close();
}

Android Database returns null

public class DBHelper extends SQLiteOpenHelper {
private static final int DB_VERSION=1;
private static final String DB_NAME="SAMPLE.db";
private static final String TABLE_NAME="events";
private static final String KEY_ID="sampleId";
private static final String KEY_TITLE="sampleTitle";
private static final String KEY_DATE="sampleDATE";
SQLiteDatabase dbEvents;
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS sampleTable(sampleID INTEGER PRIMARY KEY AUTOINCREMENT,sampleTitle TEXT,sampleDATE BIGINT,trash INTEGER DEFAULT 0) ");
this.dbEvents=db;
}
public Integer deleteItem(Integer itemId){
Log.d("CURSOR:","IM HERE"+eventId);
if(dbEvents == null){
Log.d("CURSOR:","IM NOT INTIALIZING");
}
return null;
}
Where I'm getting IM NOT INTIALIZING
and in my Activity I'm calling as [When Delete Button is clicked]
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dbHelper=new DBHelper(this);
}
public void deleteItem(int Id){
dbHelper=new DBHelper(this);
dbHelper.deleteEvent(Id);
}
I cannot perform DB operation where it throws to Null Pointer Exception.
thanks in advance
onCreate will be called, when you call getWritableDataBase() method with an instance of your DBHelper.
From the Javadocs for the method getWritableDataBase() with an instance of a class that extends SQLiteOpenHelper
Create and/or open a database that will be used for reading and writing. The first time this is called, the database will be opened and onCreate, onUpgrade and/or onOpen will be called.
This means, that this code
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS sampleTable(sampleID INTEGER PRIMARY KEY AUTOINCREMENT,sampleTitle TEXT,sampleDATE BIGINT,trash INTEGER DEFAULT 0) ");
this.dbEvents=db;
}
won't get you far. Since creating by calling getWritableDataBase or getReadableDataBase returns a SQLiteDatabase instance for performing SQLite operations.
So, from an Activity if you want to access your Database you have to do the following:
DBHelper dbHelper = new DBHelper(this);
SQLiteDatabase db = dbHelper.getWritableDataBase();
db.query("SELECT * FROM " + sampleTable);

Categories