Markus
Markus

Reputation: 1563

how to open database only once in a android project

I want to open my database only once, but somehow I cant figure it out yet.

My MainApplication.java defines how to open the database:

public static MySQLiteHelper openDatabase() {
    if (dbHelper == null) {
        dbHelper = new MySQLiteHelper(getInstance().getApplicationContext());
    }
    database = dbHelper.getWritableDatabase();
    return dbHelper;
}

and in my MainActivity.java I open the database:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MainApplication.openDatabase();
    // ...

this activity has some Fragments, which have some Subfragments. When I try to access the database with one of those fragments I get the following exception:

02-14 14:17:46.945: E/AndroidRuntime(29537): FATAL EXCEPTION: main
02-14 14:17:46.945: E/AndroidRuntime(29537): java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/at.itn.android.belegscanner/databases/belegscanner.db
02-14 14:17:46.945: E/AndroidRuntime(29537):    at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
02-14 14:17:46.945: E/AndroidRuntime(29537):    at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1156)
02-14 14:17:46.945: E/AndroidRuntime(29537):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1032)
02-14 14:17:46.945: E/AndroidRuntime(29537):    at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1200)
02-14 14:17:46.945: E/AndroidRuntime(29537):    at at.itn.android.belegscanner.db.dao.impl.DataSourceImpl.getAllElements(DataSourceImpl.java:45)

A fix would be to do MainApplication.openDatabase(); everytime I create a fragment, but that cant be the correct way to do it. Can someone give me a hint how to do it correctly?

Upvotes: 0

Views: 614

Answers (1)

Pablo Santa Cruz
Pablo Santa Cruz

Reputation: 181380

You should not use an activity for this. It's better to use Application class for this.

Something like this:

public class MyDatabaseApplication extends Application {

    private MySQLiteHelper dbHelper;

    public MyDatabaseApplication() { openDatabase(); }

    private void openDatabase() {
       // open db here
       dbHelper = ...; //
    }

    public Connection getConnection()
    {
        return dbHelper.getWritableDatabase();
    }

}

Then, in your manifest make sure you define application's class:

<application android:name="MyDatabaseApplication" android:icon="@drawable/icon"     android:label="@string/app_name">

In other parts of your code (for instance, Activities) you will use:

Connection c = ((MyDatabaseApplication) this.getApplication()).getConnection();

Upvotes: 1

Related Questions