What is the difference between SQLiteOpenHelper.close () and SQLiteDatabase.close ()?

What happens when I call SQLiteOpenHelper.close()and what happens when I call SQLiteDatabase.close()?

For my Android applications, I always create a subclass of the class Applicationthat has a single instance MySQLiteOpenHelper, which is a subclass SQLiteOpenHelperthat will be used by all application components such as Services, Activities and BroadcastReceivers.

As MySQLiteOpenHelperI have the only copy SQLiteDatabase. I create an instance MySQLiteOpenHelperin the Application.onCreate () method and never call close()in any of the instances SQLiteOpenHelperor SQLiteDatabase. Although I call close () explicitly for every cursor object returned query(), and on every SQLiteStatementone that I use to insert, update or delete data.

So far, it has worked fine without any problems. But lately, I get crashlogs from user. The exception is SQLiteDatabaseLockedException. I read the documentation that says

Abandoned, if the database engine could not get the database locks, it needs to do its job.

I don’t understand how they can be a problem when acquiring a database lock, when there is only one database instance that I use, and the documentation says that all database calls are serialized by the system. Nor do I start or end any database transactions using beginTransaction () or any other method associated with it.

After some searching, I think I should call close()in my database connection.

My questions:

  • I use the correct approach here (I do not need to exchange data with other applications or third-party applications, so as not to use ContentProviders)?

  • When do I need to close the database connection?

  • Also, should I close MySQLiteOpenHelperor SQLiteDatabase?

Code for MySQLiteOpenHelper.java:

public class MySQLiteOpenHelper extends SQLiteOpenHelper {

        public static String TAG = Common.MAIN_TAG + "MySQLiteOpenHelper";

        public static int DATABASE_VERSION = 19;

        private static String DB_PATH = null;
        public static final String DB_NAME = "data.sqlite";
        private SQLiteDatabase db;

        private final Context context;

        /**
         * Constructor Takes and keeps a reference of the passed context in order to
         * access to the application assets and resources.
         * 
         * @param context
         */
        public MySQLiteOpenHelper(Context context) {
            super(context, DB_NAME, null, DATABASE_VERSION);
            DB_PATH = "/data/data/" + context.getPackageName().replace("/", "")
                    + "/databases/";
            this.context = context;
        }

        /**
         * Creates a empty database on the system and rewrites it with your own
         * database.
         * */
        public void createDataBase() throws IOException {

            // Log.v(TAG, "Create database checkpoint - 1");
            boolean dbExist = checkDataBase();
            // Log.v(TAG, "Create database checkpoint - 2");
            if (dbExist) {
                // Log.v(TAG,
                // "Create database checkpoint - 3 - database already exists");
            } else {
                // Log.v(TAG,
                // "Create database checkpoint - 3 - database needs to be copied");
                // Log.v(TAG, "Create database checkpoint - 4");
                try {
                    copyDataBase();
                    checkDataBase();
                    // Log.v(TAG,
                    // "Create database checkpoint - 5 - database cpoied");
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new Error("Error copying database");
                }
            }
        }

        void copyDatabaseToSdCard() throws IOException {
            if (Log.isInDebugMode()) {
                InputStream input = null;
                FileOutputStream output = null;

                int c;
                byte[] tmp;
                try {
                    File databaseFile = new File(
                            Environment.getExternalStorageDirectory(),
                            Common.MAIN_TAG + "sqlite");
                    if (databaseFile.exists()) {
                        databaseFile.delete();
                    }
                    databaseFile.createNewFile();
                    output = new FileOutputStream(databaseFile);
                    int i = 0;

                    input = new FileInputStream(new File(DB_PATH + DB_NAME));
                    tmp = new byte[1024];
                    while ((c = input.read(tmp)) != -1) {
                        i++;
                        output.write(tmp, 0, c);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (input != null) {
                        input.close();
                    }
                    if (output != null) {
                        output.close();
                        output.close();
                    }
                }
            }
        }

        /**
         * Check if the database already exist to avoid re-copying the file each
         * time you open the application.
         * 
         * @return true if it exists, false if it doesn't
         */
        private boolean checkDataBase() {
            // Log.v(TAG, "Check database checkpoint - 1");
            SQLiteDatabase checkDB = null;
            try {
                // checkDB = getWritableDatabase();
                String myPath = DB_PATH + DB_NAME;
                checkDB = SQLiteDatabase.openDatabase(myPath, null,
                        SQLiteDatabase.OPEN_READWRITE);
                // Log.v(TAG,
                // "Check database checkpoint - 2 - got database file on device");
                checkDB.close();
                getWritableDatabase().close();
                // Log.v(TAG, "Check database checkpoint - 3");
            } catch (Exception e) {
                // Log.v(TAG,
                // "Check database checkpoint - 4 - database does not exists on device");
                // database does't exist yet.
                if (checkDB != null)
                    checkDB.close();
                // Log.v(TAG, "Check database checkpoint - 5");
            }

            return checkDB != null ? true : false;
        }

        /**
         * Copies your database FROM your local raw-folder to the just created empty
         * database in the system folder, FROM where it can be accessed and handled.
         * This is done by transfering bytestream.
         * */
        private void copyDataBase() throws IOException {
            // Log.v(TAG, "Copy database checkpoint - 1");
            InputStream input = null;
            FileOutputStream output = null;
            SQLiteDatabase myDB = null;

            myDB = context.openOrCreateDatabase(DB_NAME, 0, null);
            if (myDB != null) {
                myDB.close();
            }

            int c;
            byte[] tmp;
            try {
                File databaseFile = new File(DB_PATH, DB_NAME);
                databaseFile.mkdirs();
                databaseFile.createNewFile();
                output = new FileOutputStream(DB_PATH + DB_NAME);
                int i = 0;

                input = context.getResources().openRawResource(R.raw.hcgtabletdb);
                tmp = new byte[1024];
                while ((c = input.read(tmp)) != -1) {
                    i++;
                    output.write(tmp, 0, c);
                }
                // Log.v(TAG, "Finished copying database");
            } catch (Exception e) {
                e.printStackTrace();
                // Log.e(TAG, "Error in copying database" + DB_NAME);
            } finally {
                if (input != null) {
                    input.close();
                }
                if (output != null) {
                    output.close();
                    output.close();
                }
            }
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            createDataBase();
        }

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

        public int getIdFor(String name) {
            String query = "SELECT * FROM bloodpressure WHERE userid=" + userId
                + " ORDER BY createdon, timecreatedon";
            Cursor cur = db.rawQuery(query, new String[] {});
            int id = cur.getInt(0);
            cur.close();
            return cur;
        }
}

Code for MyApplication.java

public class MyApplication extends Application {

    private static MyApplication singleton;
    private MySQLiteOpenHelper dbHelper;

    public static MyApplication getInstance() {
        return singleton;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        singleton = this;
        dbHelper = new MySQLiteOpenHelper(getApplicationContext());
        // Some code
    }

    public MySQLiteOpenHelper getDatabaseHelper() {
        return dbHelper;
    }

}

:

int id = MyApplication.getInstance().getDatabaseHelper().getIdFor("ashish");
+5
1

SQLiteOpenHeloper::close() SQLiteDatabase::close().

SQLiteOpenHeloper::close() - SQLiteDatabase::close().

, , SQLiteOpenHelper , .

. . SQLiteOpenHelper , SQLiteOpenHelper, .

sqlite SQLiteOpenHelper

SQLiteOpenHelper::close():

/**
 * Close any open database object.
 */
public synchronized void close() {
    if (mIsInitializing) throw new IllegalStateException("Closed during initialization");

    if (mDatabase != null && mDatabase.isOpen()) {
        mDatabase.close();
        mDatabase = null;
    }
}
+1

All Articles