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;
public MySQLiteOpenHelper(Context context) {
super(context, DB_NAME, null, DATABASE_VERSION);
DB_PATH = "/data/data/" + context.getPackageName().replace("/", "")
+ "/databases/";
this.context = context;
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
} else {
try {
copyDataBase();
checkDataBase();
} 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();
}
}
}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READWRITE);
checkDB.close();
getWritableDatabase().close();
} catch (Exception e) {
if (checkDB != null)
checkDB.close();
}
return checkDB != null ? true : false;
}
private void copyDataBase() throws IOException {
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);
}
} catch (Exception e) {
e.printStackTrace();
} 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());
}
public MySQLiteOpenHelper getDatabaseHelper() {
return dbHelper;
}
}
:
int id = MyApplication.getInstance().getDatabaseHelper().getIdFor("ashish");