简体   繁体   中英

How to store database instance in Android so that it doesnt become null?

I have several database accesses in my Android Application and hence I have a created a class with a static variable, so that I can store a single instance of the database for the whole application. Quite often, this instance becomes null. Hence I have checks all over the place if at all the instance becomes null, which i added after getting the null pointer error and to reinitialize it in this way :

public class DatabaseInstance {
    public static StoreDbHelper db = null;

    public DatabaseInstance(Context c){
        db = new StoreDbHelper(c);
    }

    public static StoreDbHelper getCheckedDatabaseInstance(Context c){
        if(db == null){
            db = new StoreDbHelper(c);

        }
        return db;
    }
}

Even tough I do this, sometimes I still get db to be null. I have a feeling there is a better way to do this, I have now added db!=null checks all over, but is there a better way to reinitialize the variable or may be store it somewhere? My error is in the code below (before I added all the db !=null checks), it says

java.lang.NullPointerException: Attempt to invoke virtual method 'java.util.ArrayList com.example.ramapriyasridharan.localstore.StoreDbHelper.getAccelerometerTable()' on a null object reference 

This means that my variable db is null right? I located the error to the line in the code below:

if(taskParams.getTag().equals(SEND_SUMMARIZED_DATA)) {
                if(db==null){
                    db = DatabaseInstance.getCheckedDatabaseInstance(this);
                }
                final Runnable run_summarized = new Runnable() {
                    @Override
                    public void run() {
                        // ACCELEROMETER
                        if (db != null) {
                            //This is the error below!!!!!!!!!!!!!!!!!!
                            ArrayList<AccelerometerStoreReturn> p = db.getAccelerometerTable();
                            if (p != null && db != null) {

My question is, how should I keep one instance of the db object for the application, and why again does it repeatedly become null??

Note : StoredbHelper is a class that has the creation of my database and insertions deletions so on... as methods. As I mentioned before the error seems to come for the fact that db is null. This is the constructor below:

public StoreDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

This is my getAccelerometer table is it helps :

public ArrayList<AccelerometerStoreReturn> getAccelerometerTable(){
        String q = "SELECT * FROM "+TABLE_STORE_ACCELEROMETER;
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(q, null);
        ArrayList<AccelerometerStoreReturn> p = new ArrayList<AccelerometerStoreReturn>();
        while(cursor.moveToNext()){
            p.add(new AccelerometerStoreReturn(cursor.getLong(4),cursor.getInt(5),cursor.getFloat(1),cursor.getFloat(2),cursor.getFloat(3),cursor.getInt(6),cursor.getInt(0)));
        }
        cursor.close();
        Log.d("DB", "p.size ="+p.size());
        return p;
    }

And this is how I initialize db :

StoreDbHelper db = DatabaseInstance.getCheckedDatabaseInstance(this);

Thank you for your time!!

Helper Class :

public class OpenHelper {

    public static SQLiteOpenHelper singleton;
    static Context context;
    static SQLiteDatabase db;
    public static final String DATABASE_NAME = "Demo.sqlite";
    public static final int DATABASE_VERSION = 1;

    public static SQLiteDatabase getDataHelper(Context context_) {
        context = context_;
        try {
            // Copy your database here
        } catch (IOException e) {
        }

        if (singleton == null) {
            openDb();
        }
        if (db != null) {
            if (!db.isOpen()) {
                openDb();
            }
        } else {
            openDb();
        }
        return db;
    }

    static void openDb() {

        singleton = new SQLiteOpenHelper(context, DATABASE_NAME, null,
                DATABASE_VERSION) {

            @Override
            public void onUpgrade(SQLiteDatabase db, int oldVersion,
                    int newVersion) {
            }

            @Override
            public void onCreate(SQLiteDatabase db) {
            }
        };
        db = singleton.getWritableDatabase();
    }


}

To access in other class :

SQLiteDatabase db = OpenHelper.getDataHelper(context);

Try modifying your DataBase class as follows.

public class DatabaseInstance {
    private static StoreDbHelper db = null;

    private DatabaseInstance(Context c){
        db = new StoreDbHelper(c);
    }

    public static StoreDbHelper getCheckedDatabaseInstance(Context c){
        if(db == null){
            db = new StoreDbHelper(c);

        }
        return db;
    }
}

By making so , you can restrict other classes accessing the StoreDbHelper db instance and modifying it.

Assuming your StoreDbHelper should be extending super class like this.

public class StoreDbHelper extends SQLiteOpenHelper

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM