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.
Related
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);
}
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 .
I am attempting to call to my database from many different areas of my app, but I am having trouble saving and retrieving objects. When I inspect my data it looks like I am getting the cursor for the right columns, but it is always returning a null object even though it seems there is data in those columns.
I'm not sure what the issue is, but it may have to do with this recursive looking call into the database I found in the variable explorer (it continues this cascading for as far as I cared to explore).
To access my SQLite DB via Android Room I use a method call such as below from any relevant class (this gets called many times from various unique objects [should I be closing it?]):
#Entity(tableName = "cell")
public class LivingCell extends AsyncTask<Integer, Integer, Integer>{
....
getCellsDB.getCell(uid);}
public CellsDBHandler getCellsDB(){
if (cellsDBHandler == null)
cellsDBHandler = CellsDBHandler.getAppDatabase(MainActivity.getContext(),uid);
return cellsDBHandler;
}
Now I was under the impression that it wouldn't create a new instance of the database handler because this is what my CellsDBHandler looks like:
#Database(entities = {LivingCell.class})
public abstract class CellsDBHandler extends RoomDatabase {
private static CellsDBHandler INSTANCE;
public abstract CellDao cellDao();
public static CellsDBHandler getAppDatabase(Context context, String cityUid) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
CellsDBHandler.class,
DBPath).build();}
return INSTANCE;
}
public LivingCell getCell(String cellUid) {
return cellDao().getCellByID(cellUid);}
}
And my CellDao
//ALL DAO CALLS ARE RETURNING NULL OBJECTS BUT HAVE POPULATED TABLES
#Dao
public interface CellDao {
#Query("SELECT * FROM cell")
List<LivingCell> getAll();
#Query("SELECT uid FROM cell")
List<String> getAllUids();
#Query("SELECT * FROM cell WHERE uid LIKE (:cellUid)")
LivingCell getCellByID(String cellUid);
#Insert(onConflict = REPLACE)
void insert(LivingCell cell);
...
Perhaps my call to MainActivity is the issue though... is this at all an acceptable way to find the application context?
private static MainActivity instance;
public static Context getContext(){
return instance;
}
Incase it matters, all my UIDs are:
//form of: 1c21df2a-5b8f-4a56-ac5b-ed385ba8e4b8
uid = UUID.randomUUID().toString();
as the cellUid is a single String, not an Array or Collection, try the following
#Query("SELECT * FROM cell WHERE uid LIKE :cellUid")
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.