Will using single database connection to sqlite never throw LockedException? - android

In my application, I am using a single instance of the Helper class which means that I have only one database connection.
public static MyHelper getInstance(Context context) {
if (instance == null) {
synchronized (MyHelper.class) {
if (instance == null) {
instance = new MyHelper(context);
}
}
}
return instance;
}
And as I am using only one connection, all my operations to the database will be serialized. It means that even if I am using multiple threads there is no need for me to take care of synchronization. It will be taken care by Sqlite. But strangely sometimes I am getting the exception that the database is locked. So what can be the reason for this exception ? How can this exception be avoided ?

Related

Do we need to create SqliteOpenHelper as Singleton Class in android

It is thread safe to use single instance of database by all activities of my Applications. And if i do so, when should i close the database connection.
Please recommend the right method to use SqliteOpenHelper .
I've been using an approach I found in an online course and haven't had a slightest issue with it. Just put a synchronized keyword for your database instance so that multiple threads could manage it at the same time. This is what I am using:
synchronized static AppDatabase getInstance(Context context) {
if (instance == null) {
instance = new AppDatabase(context.getApplicationContext());
}
return (instance);
}

Android Room: Save and export database in SQLite format

I use Room to save my data :
#Database(entities = {Colis.class}, version = 1)
public abstract class ChloeDatabase extends RoomDatabase {
public abstract ColisDao colisDao();
private static volatile ChloeDatabase INSTANCE;
public static ChloeDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (ChloeDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
ChloeDatabase.class, "my_database")
// Wipes and rebuilds instead of migrating if no Migration object.
// Migration is not part of this codelab.
.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
}
But what I really want is to save data in sdcard in sqlite format (so that I can export my_database.sqlite file in /sdcard/Android/data/my_package/my_database.sqlite, whether it's on a emulator or a real device).
I searched for a whole day on Internet without finding the solution.
Could anyone help me with this issure ?
You can extract your database, after you have connected your emulator or physical device like this:
Go to DeviceFileExplorer
data
data
find you app name
databases
and than find your database. It is the file with the larger size . Than drop it to your phone storage. After that if you want to check your data in your computer, you can perform queries in Sqlite syntax with this little toy here .

room database,What is the difference between inMemoryDatabaseBuilder and databaseBuilder?

We can get a database throw followed two methods
/**
* Copyright:MyApplication
* Author: liyang <br>
* Date:2018/6/15 下午5:07<br>
* Desc: <br>
*/
#Database(entities = {Pet.class ,User.class}, version = 1)
public abstract class RoomDb extends RoomDatabase {
private static RoomDb INSTANCE;
private static final Object sLock = new Object();
public abstract UserDao getUserDao();
public abstract PetDao getPetDao();
public static RoomDb getInstance(Context context) {
if (INSTANCE == null) {
synchronized (sLock) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),RoomDb.class,"Sample.db").build();
}
}
}
return INSTANCE;
}
public static RoomDb getInMemoreyDatabase(Context context){
if (INSTANCE == null) {
synchronized (sLock) {
if (INSTANCE == null) {
INSTANCE = Room.inMemoryDatabaseBuilder(context.getApplicationContext(),RoomDb.class).build();
}
}
}
return INSTANCE;
}
}
But I really want to know what the difference is between them!
Does getInMemoreyDatabase run faster than Room.databaseBuilder?
inMemoryDatabaseBuilder(): The database will be created in system memory, If you kill the app (Killing your process), database will be removed and data will not be persisted. This can be used while Testing.
databaseBuilder() : The database will be created in /data/data/com.your.app and will be persisted. This you will be using it in production.
inMemoryDatabaseBuilder() will build the database on a temporary basis. The database will reside in system memory and it would be destroyed as soon as the process is killed.
databaseBuilder()
it will build the database on a permanent basis and the database would be stored in /data/data/.... folder.
databaseBuilder()
Creates a RoomDatabase.Builder for a persistent database. Once a database is built, you should keep a reference to it and re-use it.
Returns
A RoomDatabaseBuilder<T> which you can use to create the database.
inMemoryDatabaseBuilder()
Creates a RoomDatabase.Builder for an in memory database. Information stored in an in memory database disappears when the process is killed. Once a database is built, you should keep a reference to it and re-use it.
Returns
A RoomDatabaseBuilder<T> which you can use to create the database.

Change database in SqliteOpenHelper

Is there a way to change what database an SQLiteOpenHelper object uses without having to force every class that uses the helper to replace their instance of the class?
The reason why I'm changing the database is because I have some live data and some offline data in two separate databases with identical table structures. I update the offline data and then swap them, allowing me to lock the offline database on big inserts.
You must use the singleton pattern to acces to your database with only one instance
it's look like
public class SingletonDemo {
private static SingletonDemo instance = null;
private SingletonDemo() { // do what you want here}
public static SingletonDemo getInstance() {
if (instance == null) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
...
// Add all the class function you need here
}
This is thread safe and can be use every where you need.

Correctly open/close a database with Singleton design pattern

I am creating an application which makes a lot of interactions with a database (both read and write operations).
To avoid open/close operations at each request, I created a class extending SQLiteOpenHelper with a Singleton design pattern. This way, I am sure only one instance of the SQLiteOpenHelper and only one connection to the database is made during all the application lifecycle (and not only activity lifecycle).
I also read some articles about ContentProvider, but I am not sure it's a better way.
So, this is the main logic of my Singleton class (onCreate and onUpgrade removed) :
public final class BaseSQLite extends SQLiteOpenHelper {
private static BaseSQLite mInstance = null;
private SQLiteDatabase db = null;
public static BaseSQLite getInstance(Context context) {
if (mInstance == null) {
mInstance = new BaseSQLite(context.getApplicationContext(),
DBNAME, DBVERSION);
}
return mInstance;
}
private BaseSQLite(final Context context, final String name,
final int version) {
super(context, name, null, version);
db = getWritableDatabase();
}
#Override
public synchronized void close() {
if (mInstance != null)
db.close();
}
public Cursor getAllData() {
String buildSQL = "SELECT * FROM myTable";
return db.rawQuery(buildSQL, null);
}
}
So, to access my database, I made this :
BaseSQLite baseSQLite = BaseSQLite.getInstance(context);
baseSQLite.getAllData();
It works perfectly for now. But my question is about the close() method. I really don't know when to call it. Actually, my database instance is the same for every Activies of my application, so I think it's a bad idea to call close() in an onPause() method, because the instance will be potentially (and it will often happens) recreated in the onStart() method of the next Activity. Also, I can't detect the end of my application, i.e. when no activity is visible on the screen anymore.
Can somebody give me some help about this issue ? I found some answer when the database is linked to ONE activity, but no really hint is given for my case.
You should call close anytime you are done writing to your database. For example when you insert data, you will have an open connection to the database that should be closed when it is done.
Reading is different. When you create a SQLite database on your phone, the data is persistent. The database exists and the handler you create provides a convenient way to access that information. Reading the database usually takes place by getting a readable instance of the database and using a Cursor to extract values. In that case you close the cursor when you're done, not the database itself.
You're right that you should not be closing the database connection during separate activities' lifecycle methods. Instead, as suggested above, close the database connection in your handler's methods that write to the database when you are done performing that transaction.

Categories

Resources