I have database updates like the two below, throughout my code. Most of my updates open the database first before updating the record and then closes the database after the record has been updated. I have noticed that not using this statement: mDb = Helper.getWritableDatabase(); before the insertion and this statement: mDb.close(); after insertion, will cause a force close error sometimes, but not always. What is the proper way. Do I use the open and close statements all the time or only when I have to or should I always open and then close during the update process. What is the proper technique. Here is the snippet with the open close statements. Thanks in advance. Is the open statement necessary?
// Open connections to the database
mDb = Helper.getWritableDatabase();
// update 1
String strFilter7 = "_id=" + 7;
ContentValues args7 = new ContentValues();
args7.put(COL_VALUE, newB1ftgvalue);
mDb.update("VarData", args7, strFilter7, null);
// update 2
String strFilter11 = "_id=" + 11;
ContentValues args11 = new ContentValues();
args11.put(COL_VALUE, newB2ftgvalue);
mDb.update("VarData", args11, strFilter11, null);
// closes database
mDb.close();
It is good practice to always call close() after you are done with database updates. If you haven't closed the database you may see errors. Once database is open, you may do multiple updates. It shouldn't be an issue. One thing to take care is, it is better not to keep open connection for long time due to lot of reasons. Here is good discussion on this topic.
Do not close it and do only have one sqlite helper. It's basically a static openhelper. There is no problem with never closing your database. This link gives a good piece of code that works great. You will not have memory leaks with an open database. You will however have problems with open cursors, so make sure to close those.
http://www.touchlab.co/blog/single-sqlite-connection/
A good discussion is here:
What are the best practices for SQLite on Android?
I realized the link I posted has changed since when I once first viewed it. Change:
instance = new DatabaseHelper(context);
to
instance = new DatabaseHelper(context.getApplicationContext());
and
public class DatabaseHelper extends OrmLiteSqliteOpenHelper
to
public class DatabaseHelper extends SqliteOpenHelper
You need to open the db as a writable database in order to modify its data, so yes, you have to open it before updating records.
Related
Firstly, I create a database called "mydb" in my Android app:
DBHelper dbHelper = new DBHelper(context, "mydb", null, 1);//DBHelper is my custom class
And write some data into it's table:
SQLiteDatabase db = dbHelper.getReadableDatabase();
db.execSQL("insert into mytable(name, text) values ('allen','hello')");
Here, everything is ok. But then, i delete this database manually not by programming, with a software "R.E. explore" (Certainly on a rooted device).
Then, in my code, i read this table of the database. What is astonishing is that i still could get the data I stored.
Cursor cursor = db.query("mytable", new String[]{"name","text"}, null, null, null, null, null);
Why?
Quoting from the Android Developers reference website:
Once opened successfully, the database is cached, so you can call
this method every time you need to write to the database. (Make sure
to call close() when you no longer need the database.)
This is from the description of the getWritableDatabase() method, however both getReadableDatabase() and getWritableDatabase() return basically the same object for reading the database.
Please note that you should use getWritableDatabase() if you want to persist the changes you make to the database on the device's internal memory. Otherwise they will be valid only for the duration of the application's runtime and will be discarded once the app is closed. If you wish to delete the database completely, you should call the SQLiteDatabase's close() method in order to invalidate the cache.
use SQLiteDatabase.deleteDatabase(File file) API to delete the database
Deletes a database including its journal file and other auxiliary files that may have been created by the database engine.
Make sure you have closed all the connections that are open.
In case you are not able to do that,
just cal the deleteDatabase followed by kill process.. - not recommended
You need to delete the app from your phone then install again
I am trying to write a code in Android and going through following errors. I am opening a SQLite database and using Cursor.
Java Code
for(int y3=0;y3<10;y3++)
{
String sql_query5= "SELECT * FROM Data WHERE Id="+y3+"";
Cursor cur5 = SQLiteDatabase.openDatabase(db, null, SQLiteDatabase.OPEN_READWRITE).rawQuery(sql_query5, null);
if(cur5.moveToNext())
{
//
}}
So i need to display the Age in the layout but i am facing SQLiteCantOpenDatabaseException and Database object not closed. I don't understand the errors.
Please let me know some solution and suggestion !!!
Do not use hard-coded file paths. You have no guarantees about the structure of the filesystem.
Learn to use SQLiteOpenHelper. This is what helps you create and maintain your SQLite database. Instead of trying to open the database yourself, you create a new SQLiteOpenHelper and call getReadableDatabase().
When you are done reading from a Cursor, call cursor.close().
If you want to close the database, you can call close() on it as well; just be aware that any cursors you got by querying it will no longer be able to give you data, so make sure you are finished them those before closing the database.
add '' in your
String sql_query5= "SELECT * FROM Data WHERE Id='"+y3+"' ";
I have an app that uses a database with 3 tables in it. Those 3 tables have data read from and written to them by activities and services.
Having gotten a few "android.database.sqlite.SQLiteException: database is locked" crashes, I went in to the database adapter class and wrapped every write, update, or delete function with a synchronized statement, so like:
public int deleteExpiredAlarms() {
String whereClause = FIELD_EXPIRED + " = 1";
int val = 0;
synchronized(dbWriteLock) {
val = db.delete(ALARM_DATABASE_TABLE, whereClause, null);
}
return val;
}
That seemed to make it better. But lately it's gotten bad again as I've added more services that read and write to different tables.
Do I need to synchronize ALL db access statements, including queries?
The exception is occurring on the attempt to open the writable database via the open helper...should I synchronize that act also?
I've heard that I should only be using one db helper so that there won't be issues with multiple threads accessing the db. How do I use only one db helper? Every example I've seen so far has the db helper as an instantiated value inside the db adapter....so wouldn't that be a separate db helper per db adapter instantiated (one in an activity, one in a service running,etc)
I've looked at using a content provider instead, as it's been claimed to solve problems like this, but it's really more work than I want to do if I should be able to have direct db access without locking issues. And I do not plan to make this db accessible to other apps.
Thanks for the help.
I use the following method for reading/writing db:
Database is located at /data/data/{packagename}/databases/Database.db
Since the database is greater than 3Mb we found a specific solution to have it copied there and to have it populated with appropriate data.
Following is the class implementing the task to get the opened database. This class is a singleton.
public class DatabaseHelper extends SQLiteOpenHelper
to open the database we use the following method:
SQLiteDatabase db = DatabaseHelper.getInsance().getReadableDatabase();
Then rawquery is used for querying the db:
Cursor cursor = db.rawQuery(query, null);
Then best fitting to our purposes we fetch the database data into memory in different resultset instances:
while (cursor.moveToNext()) {
ResultSet rs = new ResultSet();
rs.setThis(cursor.getInt(0));
rs.setThat(cursor.getString(1));
// and so on.. this is just an example
ResultList.add(rs);
}
Finally:
cursor.close();
db.close();
Let mention, if necessary, transaction is used also, but using transaction didn't lead to speed-up.
For every single query the pattern above is (quite) followed. But unfortunately this solution seems very slow. So some method profiling is made and it came to clear, that sqlite setlocale is always run at getReadableDatabase() (which is created! don't forget) and that method takes the most of the time. Meanly 40% alone..
Please advice how to solve this problem! Or maybe please offer an other pattern to satisfy our needs!
Thanks in advance
Szia!
Funniest thing is, native_setLocale (which is causing the slow DB open) apparently doesn't even work: http://code.google.com/p/android/issues/detail?id=2625
6) Finally:
cursor.close();
db.close();
It's not possible to keep the database open between queries?
As with the question posed here (SQLCipher for Android getReadableDatabase() Overherad) the performance issue you are seeing is likely due to SQLCipher key derivation. Performance for opening a database is deliberately slow due to key derivation. You should cache the database connection so that it can be used multiple times without having to open and key the database repeatedly. If this is possible, opening the database once during startup is the preferred course of action. Subsequent access on the same database handle will not trigger key derivation, so performance will be much faster.
I am using my own SQLite3 database as opposed to creating a new one each time my app runs, as I have a few tables with static data that I am trying to display. I created my database and placed it in my assets folder. I then created my database helper and when I start my app I can open my database without problem but when I try to open my first table using the following code
private Cursor getData()
{
try
{
myDbHelper = new DatabaseHelper(this);
SQLiteDatabase db = myDbHelper.getReadableDatabase();
Cursor cursor = db.query("exhibitor", FROM, null, null, null,null, ORDER_BY);
startManagingCursor(cursor);
return cursor;
}
catch(SQLiteException e)
{
String err = e.toString();
return null;
}
}
It throws an error saying android.database.sqlite.SQLiteException: no such table: exhibitor: , while compiling: SELECT _id, EXHIBITOR FROM exhibitor ORDER BY EXHIBITOR but when I check the database exhibitor is there.
What am I missing?
Settings -> Applications -> Manage Applications -> (Click on your application) -> Clear data
Whenever you create new table in an existing database the table doesnt create because the OnCreate function of database handler will not be called everytime but only if required(like database not initiated). If that is not the case your newly created table actually hasnt created. Clear the data to force the db to instantiate itself.
Have you moved the database from the assets folder to /data/data/YOUR_PACKAGE/databases/ on the emulator?
This is a good detailed post about moving the database to /data/data/YOUR_PACKAGE/databases/ if it does not exist.
Here is another short and simple solution to it.
Clear Data and uninstall application from your device and re-install application in device...
Settings -> Applications -> Manage Applications -> Your Application Name -> Clear data
Using SQLiteOpenHelper.onCreate() does not create a new database every time your app starts - rather it creates a database if it does not already exist.
It sounds like you might have an empty database created by or for your helper (if there was no database at all, I might expect a different exception), and your separate database that you created outside of Android. Looks like you and your app are not looking in the same place for your data.
Just clearing the data did not work for me.
What worked was:
Uninstall app
Restart device or emulator
Disable Instant run (Not just the main group but all individual instant run settings)
Build -> Clean Project
Build -> Rebuild Project
hapend to me once
change your DATABASE_VERSION
if your DATABASE_VERSION =1 it will see just three table
if your DATABASE_VERSION = 2 it will see just more table but i really didn't know how many
good luck
I just had a simple mistake.
Reason:
Solution:
Just happened to me. I don't exactly know why but changing the DB_VERSION attribute to a bigger number made it work. The thing is: each time i'm changing the fields of the DB (attributes of the SQLiteDB class), i need to change that number.
Here is my answer according to the description of #ReivieraKid.
No, Uninstall, No Restart, Just checking the app memory if it is your real database, if return false, then copy the database to the memory again. Then You will All set. But to apply this method, you have to know the minimum size of your database.
https://stackoverflow.com/a/73332470/7608371