3

I have a custom DataBaseHelper class which extends SQLiteOpenHelper,which looks like this :

package com.stampii.stampii.comm.rpc;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.ResultSet;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

public class DataBaseHelper extends SQLiteOpenHelper{

    private static SQLiteDatabase sqliteDb;
    private static DataBaseHelper instance;
    private static final int DATABASE_VERSION = 1;
    // the default database path is :
    // /data/data/pkgNameOfYourApplication/databases/
    private static String DB_PATH_PREFIX = "/data/data/";
    private static String DB_PATH_SUFFIX = "/databases/";
    private static final String TAG = "DataBaseHelper";
    private Context context;

    /***
     * Contructor
     * 
     * @param context
     *            : app context
     * @param name
     *            : database name
     * @param factory
     *            : cursor Factory
     * @param version
     *            : DB version
     */
    public DataBaseHelper(Context context, String name,
                    CursorFactory factory, int version) {
            super(context, name, factory, version);
            this.context = context;
            Log.i(TAG, "Create or Open database : " + name);
    }

    /***
     * Initialize method
     * 
     * @param context
     *            : application context
     * @param databaseName
     *            : database name
     */
    public static  void initialize(Context context, String databaseName) {
            if (instance == null) {
                    /**
                     * Try to check if there is an Original copy of DB in asset
                     * Directory
                     */
                    if (!checkDatabase(context, databaseName)) {
                            // if not exists, I try to copy from asset dir
                            try {
                                copyDataBase(context, databaseName);
                            } catch (IOException e) {
                                    Log.e(TAG,"Database "+ databaseName+" does not exists and there is no Original Version in Asset dir");
                            }
                    }

                    Log.i(TAG, "Try to create instance of database (" + databaseName
                                    + ")");
                    instance = new DataBaseHelper(context, databaseName,
                                    null, DATABASE_VERSION);
                    sqliteDb = instance.getWritableDatabase();
                    Log.i(TAG, "instance of database (" + databaseName + ") created !");
            }
    }

    /***
     * Static method for getting singleton instance
     * 
     * @param context
     *            : application context
     * @param databaseName
     *            : database name
     * @return : singleton instance
     */
    public static final DataBaseHelper getInstance(
                    Context context, String databaseName) {
            initialize(context, databaseName);
            return instance;
    }

    /***
     * Method to get database instance
     * 
     * @return database instance
     */
    public SQLiteDatabase getDatabase() {
            return sqliteDb;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
            Log.d(TAG, "onCreate : nothing to do");

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            Log.d(TAG, "onUpgrade : nothing to do");

    }

    /***
     * Method for Copy the database from asset directory to application's data
     * directory
     * 
     * @param databaseName
     *            : database name
     * @throws IOException
     *             : exception if file does not exists
     */
    public void copyDataBase(String databaseName) throws IOException {
            copyDataBase(context, databaseName);
    }

    /***
     * Static method for copy the database from asset directory to application's
     * data directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @throws IOException
     *             : exception if file does not exists
     */
    private static void copyDataBase(Context aContext, String databaseName)
                    throws IOException {

            // Open your local db as the input stream
            InputStream myInput = aContext.getAssets().open(databaseName);

            // Path to the just created empty db
            String outFileName = getDatabasePath(aContext, databaseName);

            Log.i(TAG, "Check if create dir : " + DB_PATH_PREFIX
                            + aContext.getPackageName() + DB_PATH_SUFFIX);

            // if the path doesn't exist first, create it
            File f = new File(DB_PATH_PREFIX + aContext.getPackageName()
                            + DB_PATH_SUFFIX);
            if (!f.exists())
                    f.mkdir();

            Log.i(TAG, "Trying to copy local DB to : " + outFileName);

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                    myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();

            Log.i(TAG, "DB (" + databaseName + ") copied!");
    }

    /***
     * Method to check if database exists in application's data directory
     * 
     * @param databaseName
     *            : database name
     * @return : boolean (true if exists)
     */
    public boolean checkDatabase(String databaseName) {
            return checkDatabase(context, databaseName);
    }

    /***
     * Static Method to check if database exists in application's data directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @return : boolean (true if exists)
     */
    private static boolean checkDatabase(Context aContext, String databaseName) {
            SQLiteDatabase checkDB = null;

            try {
                    String myPath = getDatabasePath(aContext, databaseName);

                    Log.i(TAG, "Trying to conntect to : " + myPath);
                    checkDB = SQLiteDatabase.openDatabase(myPath, null,
                                    SQLiteDatabase.OPEN_READONLY);
                    Log.i(TAG, "Database " + databaseName + " found!");
                    checkDB.close();
            } catch (SQLiteException e) {
                    Log.i(TAG, "Database " + databaseName + " does not exists!");

            }

            return checkDB != null ? true : false;
    }

    /***
     * Method that returns database path in the application's data directory
     * 
     * @param databaseName
     *            : database name
     * @return : complete path
     */
    private String getDatabasePath(final String databaseName) {
            return getDatabasePath(context, databaseName);
    }

    /***
     * Static Method that returns database path in the application's data
     * directory
     * 
     * @param aContext
     *            : application context
     * @param databaseName
     *            : database name
     * @return : complete path
     */
    private static String getDatabasePath(Context aContext, String databaseName) {
            return DB_PATH_PREFIX + aContext.getPackageName() + DB_PATH_SUFFIX
                            + databaseName;
    }

    public boolean executeQuery(String tableName,String keys,String value){
        return execQuery(tableName,keys,value);
    }

    private static boolean execQuery(String tableName,String key,String value){
        sqliteDb = instance.getWritableDatabase();
        ContentValues values = new ContentValues();
        values.put(key, value);
        sqliteDb.insert(tableName, null, values);

        return true;

    }

    public boolean updateSQL(String tableName,String key,String value){
        return updateData(tableName,key,value); 
    }

    private static boolean updateData(String tableName,String key,String value){
        sqliteDb = instance.getWritableDatabase();
        String where = "code_id=?";
        ContentValues values = new ContentValues();
        values.put(key, value);
        values.put(key, value);
        sqliteDb.update(tableName, values, where, new String[] {"3"});
        return true;
    }

    public boolean deleteSQL(String tableName){
        return deleteData(tableName);
    }

    private static boolean deleteData(String tableName){
        sqliteDb = instance.getWritableDatabase();
        String where = "code_id=?";
        sqliteDb.delete(tableName, where, new String[] {"5"});
        return true;
    }

    public Cursor executeSQLQuery(String query){
        return sqliteDb.rawQuery(query,null);
    }

}

My question is : How can I initialize the database only once and can access it from all my Activities? (Hint: I have sqlite files in my assets folder,which I copy to my system database folder when the app stars.)

Thanks in advance!

EDIT : I forgot to say that I have 2 different sqlite databases in my application and I want to be able to initialize both of them for the whole application and can use them.That's something that I was trying to do :

DataBaseHelper dbHelper;
//some code
dbHelper = new DataBaseHelper(context, "ops_sys_tpl.sqlite", null, 1);
        DataBaseHelper.initialize(context, "stampii_sys_tpl.sqlite");

        dbHelper.copyDataBase("ops_sys_tpl.sqlite");

        dbHelper.getDatabase();
        dbHelper.executeQuery("users", "objectId", "2");
        dbHelper.executeQuery("users","serverName","stampii");
        dbHelper.executeQuery("users", "objectId", "3");
        dbHelper.executeQuery("users","serverName","stampii");
        dbHelper.executeQuery("users", "objectId", "3");
Vinayak Bevinakatti
  • 40,205
  • 25
  • 108
  • 139
Android-Droid
  • 14,365
  • 41
  • 114
  • 185

2 Answers2

4

Create your instance only once like this, The same code you can add in DB handler class but I prefer to keep it seperate.

public class MyTestDatabaseInstanceHolder {

    public MyTestDBHandler DBHelper;  
    public static SQLiteDatabase m_ObjDataBase; // This is global variable to access across the applicaiton

    public static void createDBInstance(Context pContext){
        if(DBHelper == null) {
            DBHelper = new WLDBHandler(pContext); // This will be your DB Handler Class
            m_cObjDataBase = DBHelper.openAndCreateDataBase(); // Initialze the DB Note: openAndCreateDataBase is a utility method created by you to do everything an return the DB object
        }
      }
}

In your entry point (Splash Screen) call this:

MyTestDatabaseInstanceHolder.createDBInstance(getApplicationContext());

Usage - Some other Class:

MyTestDatabaseInstanceHolder.m_ObjDataBase.rawQuery(---);
Vinayak Bevinakatti
  • 40,205
  • 25
  • 108
  • 139
1

I think for initializing your Database you have to pass the context of the activity in which you are using it, so for used it in every activity you have to initialize in every activity. If I m wrong please let me know.

user370305
  • 108,599
  • 23
  • 164
  • 151
  • Actually that's the way that I'm doing it now.But how should I proceed when I have to initialize the database from helper classes? – Android-Droid Sep 16 '11 at 12:03
  • then just pass the activity reference to that helper class and use it for initializing database. – user370305 Sep 16 '11 at 12:04
  • But as per hotveryspicy suggested this is bad idea to maintain datbase state like create, open close you have to use activity's methods like onCreate(), onStop(), onDestroy() that's why I suggeste you to initialize database in activity. Thanks. :-) – user370305 Sep 16 '11 at 12:07
  • @user370305 How to pass the activity reference? My dbhelper expects mainActivity context and I am unable to pass this context of mainActivity from my contentProvider/ –  Mar 20 '14 at 19:23