Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how should I open and close my database properly

Tags:

android

sqlite

I have an app which stores some data in a SQLite DB.Also I'm doing a lot of query an requery in my app.I have about 15 activities in it.And almoust all use the DB to query for data. But what I'm doing is opening my DB in every activity and close it in onDestroy{...} of every activity.

The problem is that onDestroy{...} may never get called and sometimes my app stays on for a long time and I switch from an activity to another opening for to many times my DB.

And sometimes I get errors like-database too many times opened and never closed.

I would try to close my DB exactly after I get my data from it and close it...moving to my next activity and re-opening and so on..... But the problem is that in some activities I come back from other activities....closing my DB and coming back to that activity would produce a big Force Close.

What I wanna do is open my DB at the beginning of my app and close it at the end of it, but I'm facing 2 problems:

1. Should I make my SQLiteOpenHelper class a singleton?...get an instance of it..open it in my first activity and then in my following activities just get an instance of my DB which is already opened/???

2.Where is the end of my app????How should I know where is the end of my app and where to close my DB.

EDIT:

public class DBAdapter extends SQLiteOpenHelper {

    public DBAdapter(Context context) {
        super(context, DATABASE_NAME, null, 1);
        this.myContext = context;

    }


    public void openDataBase() throws SQLException {
        
        
        

        String myPath = DATABASE_PATH + DATABASE_NAME;
        db = SQLiteDatabase.openDatabase(myPath, null,
                SQLiteDatabase.OPEN_READWRITE);
        

    }

}

That is a piece of code from my class that manages my DB.To make this singleton I should use a constructor likw this:

private DBAdapter()
{



//nothing in here

}

But this is undefined for SQLiteOpenHelper

EDIT FINAL: This is how I did it according with zirael advice:

package com.Server_1;

import android.app.Application;

public class MyApplication extends Application{

private static DBAdapter db;

public void onCreate()
{
    
    db=new DBAdapter(getApplicationContext());
    db.createDatabase();
    db.openDataBase();
}

public static DBAdapter getDatabaseAdapter()
{
    return db;
}


}

In every activity I where I need DB connection I do this:

MyApplication myApplication = (MyApplication) this.getApplication();

DBAdapter db= myApplication.getDatabaseAdapter();

And finally my manifest looks like:

<application  android:icon="@drawable/icon"  
android:label="@string/app_name"
  android:name=".MyApplication" 
  android:debuggable="true">
   
like image 872
adrian Avatar asked Jun 15 '11 10:06

adrian


2 Answers

In my app I open connection to database in myApplication class (your custom class that extends Application - it should be named the same as your application in androidManifest).

AndroidManifest.xml

<application android:label="@string/app_name" 
    android:name="com.mypackage.MyApplication " android:debuggable="true">

MyApplication .java

public class MyApplication extends Application {

    private DatabaseAdapter dbAdapter;


    @Override
    public void onCreate() {
        dbAdapter = new DatabaseAdapter(getApplicationContext());
        dbAdapter.open();
    }

And in each class that need db connection I simply use:

MyApplication myApplication = (MyApplication) this.getApplication();
DatabaseAdapter dbAdapter= myApplication.getDatabaseAdapter();

MyApplication is run automatically on every application start. This way I keep only one connection to DB so it's closed when app is being removed from memory without any problem.

like image 156
zirael Avatar answered Sep 19 '22 00:09

zirael


When you retrieve your dbAdapter from you MyApplication class, do it in a lazy fashion, creating it only when needed. In my implementation, I also open it at this time.

public static DbAdapter getDbAdapter() {
    if (dbAdapter == null) {
        dbAdapter = new DbAdapter();
    }
    dbAdapter.open();
    return dbAdapter;
}

It is a good idea to use getReadableDatabase() or getWriteableDatabase() in the open method of your database adapter.

Also, I think it works better to retrieve your adapter in onStart() and close it in onStop() of the activities where it is being used, rather than using onCreate() and onDestroy().

@Override
protected void onStop() {
    super.onStop();
    MyApp.closeDatabase();
}

And in the MyApp class...

public static void closeDatabase() {
    dbAdapter.close();
}
like image 39
Thomas Williams Avatar answered Sep 21 '22 00:09

Thomas Williams