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 .
Related
hey there so i'm having a small design issue where I have a flow of data coming from my RoomDb but when I first open the app the RoomDd does not instantiate till I open the activity where I am using it so this causes me to get a null data object followed by an object with the data. I just wanted to know if there was a way for me to open up my RoomDb as soon as I open my Application
I am using Dagger Hilt for Injection
output of data on opening activity
please do let me know if there is anymore info I can provide about this problem
thanks!
I recommand you to follow this codelab from the documentation, which shows how to use Room properly.
You will initialize your ViewModel class inside the activities where you want to access your data,
private ViewModel mViewModel;
give it a value inside the onCreate() method of your activity
mViewModel = new ViewModelProvider(this).get(ViewModel.class);
and the ViewModel will call the getDatabase() method below inside its constructor
static RoomDatabase getDatabase(final Context context) {
if (INSTANCE == null) {
synchronized (RoomDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
RoomDatabase.class, "database")
// Prepopulate from a .db file
.createFromAsset("database/database.db")
// Or from code --> check this step from the codelab
// https://developer.android.com/codelabs/android-room-with-a-view#12
// .addCallback(sRoomDatabaseCallback)
.build();
}
}
}
return INSTANCE;
}
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);
}
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.
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 ?
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.