I have a problem with my database.
Basically my applications read texts and rates of text from my SQLite database and show it on screen. I have also Thread function which downloads content from external internet server and uploads it into the database.
On less popular devices (mostly tablets) it generates errors like:
DB close exception
DB locked
Someone advised me to create something called a singleton to handle this and I created it but it generates errors. So I have an idea to use AsyncTask instead of Thread; do you think it will help?
Maybe you have other solutions?
AsyncTask will not help you here. You have to create a database connection as a singleton.
You should get a readable database for when you are reading and a writable database for when you are writing. Then you will be able to do both at the same time.
Both of the methods are in the SQLHelper class
Never close the DB. Make sure you have only one Helper instance per application.
See this for reference SQLiteDatabase close() function causing NullPointerException when multiple threads
This may help you :)
Related
I am working on a chat application and in chat we are getting lots of update from server. And we are also saving the updates into the local SQLite database file.
Can someone suggest me, after every single insertion/update, should we close the database or we should close the database when it is actually needed ?
Closing the connection throws away the page cache, and requires that the schema version is checked and the entire schema is re-parsed the next time it is opened.
In most apps, there are not enough database accesses so that the overhead of continually re-opening the database would actually become noticeable. But this is no reason to add useless code to your app.
Please note that the SQLiteDatabase object is reference counted. So if you are using a global open helper instance, you can keep the DB open with an extra getWritableDatabase() call, even when all your other code calls close().
You should close the connection after each query.
In .net (and in most other frameworks), SQLConnections are stored in the background anyway. It won´t hit your runtime.
Also: connection pooling is your friend.
I have an android application in which I am using Content Provider on top of the database. However, I see that database gets created only when I insert the first record in the database through the Insert of Content Provider. In this scenario, if there's an error in database creation that would remain pending till the insertion of a record.
I would like to know if there's a way I can create the database when the app is accessed for the first time, so, any possible errors in the database creation appear at the earlier stage.
Within our app we show a splash screen specifically for the purpose of creating the db and initialising some application singletons. I'd recommend something similar.
You can start a db (on)Create or db (on)Upgrade by calling SQLiteDatabase#getWritableDatabase or equivalent. Remember to perform this on a background thread and use standard eventing / callbacks to understand when this (synchronous) method has completed.
If something goes wrong then you can catch that exception during start-up although you can't really recover by the sounds of it so you'll be best off not catching any exceptions and making sure your critical init code is bullet proof.
I need to write some application which will have a couple threads and these threads will be work with local database. I afraid that these threads will be compete among themselves for database. Is there any simple solution to solve this problem? I read that I can use content provider becouse then will be only one connection with database but maybe there is another solution? Thanks for all advice and tip.
Use one DataBase Helper class and create a single instance which can be accessed by both threads.
Make all the methods in DataBase Helper class as synchronized to avoid race conditions.
We all learn that resources, such as database connections, should be acquired late and released early.
Yet applying this principle to SQLite database connections on Android have caused me some headache.
I have an app that download updates from a backend server in a service working in the background, writing updates to the database at a regular basis. The problem I experience arise when the following sequence occurs:
Service opens a writable database connection
Some activity opens a readable database connection
Service closes its database connection concurrently with the activity reading data
Activity fails due to its database connection was closed
Both the service and the activity uses the same SQLiteOpenHelper class, though different instances, to open their connections. My initial assumption was that this should work just fine, but somehow it seems that the underlying connection is shared between the two database instances.
To work around the problem I ended up not closing the database objects, only closing any opened cursors. This seems to work, though I'm not sure that I'm not leaking memory here.
Is there something obvious I am missing here?
Is there something obvious I am missing here?
I'd say no. Looking at the source code to SQLiteOpenHelper, I can't see how two instances could be sharing a SQLiteDatabase object.
Some diagnostic suggestions:
Dump the toString() value of each SQLiteDatabase, which should give you a Java instance ID. If they are the same, that is where your problem lies, and you will need to work your way upstream to figure out how the heck this is happening (e.g., you really are using the same instance of the SQLiteOpenHelper).
With your database in a stable state (i.e., no need to create or upgrade), flip one of your two database spots to use SQLiteDatabase directly, rather than via SQLiteOpenHelper, and see if that changes matters.
I am using SQLiteOpenHelper class to create, open database. for my application i am creating writable object SQLiteDatabase which i am using to read and write data to database. This object is static for main class and used in all application to read write in to database. my application is working properly on emulator. but on device after some read write query fires. why it is happening, please if any one has solution help me.
It is not recommended to have the helper as a static instance. Rather you should instanciate it each time you need to acces the DB. What might be happening is that your DB connection is getting closed by Android (because it needs memory, because there are too many open connections, ...) and when you do a query, you do not check that the connection is still open.
You can read this tutorial to get the idea of how to do it properly.
Basically inside an activity, the idea:
private void reloadData() {
MyDBHelper db = new MyDBHelper(this.getApplicationContext());
db.open();
Cursor c = db.query(...);
db.close();
// Update your data using the cursor
}
I had the same problem a few weeks ago, and I found this page, it's exactly what's wrong. The SQLite is buggy in Android and is implemented the wrong way, so you can't have threads reading and writing to the database/table at the same time.
setLockingEnabled() just dont work the way it's supposed.
What I did was running all methods that read and write to the db "Synchronized" which means you'll never have a problem with reading or writing data at the same time no matter how many threads you have.
Regards
Tobias