The best way to handle the sqlite database create and read operations - android

Althoung I have found a couple interesting posts about this topic, none of them is related to this kind of case or similar. I am developing an app which uses GoogleMaps API to show a map and I would like to have a database in which will be used to store all my points of interests (locations of e.g. police stations, hospitals, total of 478 entires) which will be placed on the map like markers aferwards.
These values will be inserted only once when the app is started for the first time, so I would guess that I do not need multiple threads or multiple instances of SQLiteHelpers in order to do this. Probably one of them should be enough to do the work, or not? Maybe it is important to mention that the users will not have a possibility to interact with the database.
I am having two activities so far, first is my InitActivity where I prepare some and check a couple of things important for the app and the second is my MainActivity. I would like to start with data insering in InitActivity as soon as the app starts but if it is possible not to wait for the whole process to ends in order to start the MainActivity, but to start it also when the data inserting starts. After the inserting finishs, I would like to call other method which will place the marker for each point of interest on the map. This method should be executed from the MainActivity. So I would need a background task which starts in one activity and informs other activity that the action is completed.
So, what could I use to carry out this kind of data inserting task and what would be the best way to do it (e.g AsyncTask - but is it possible to notify other activity that the process is completed)
Thx in advance

You are pretty much trying to invent the wheel here, which is wasting the efforts as this thing is already invented for long time. You most likely would be happy with tools like Android SQLiteAssetHelper or other similar helpers.
Android SQLiteAssetHelper
An Android helper class to manage database creation and version
management using an application's raw asset files.
This class provides developers with a simple way to ship their Android
app with an existing SQLite database (which may be pre-populated with
data) and to manage its initial creation and any upgrades required
with subsequent version releases.
It is implemented as an extension to SQLiteOpenHelper, providing an
efficient way for ContentProvider implementations to defer opening and
upgrading the database until first use.
Rather than implementing the onCreate() and onUpgrade() methods to
execute a bunch of SQL statements, developers simply include
appropriately named file assets in their project's assets directory.
These will include the initial SQLite database file for creation and
optionally any SQL upgrade scripts.

Related

(Android) Looking for pattern for managing multithreaded access to multiple databases that sometimes attach to each other

I have three separate databases in use in my app already released for iOS. The way my app works is on launch it will update 2 of the databases if any updates are detected in a separate thread. Sometimes it replaces the files completely and sometimes it merely adds new records.
In another thread, these three databases might be accessed at anytime. This would be ok except that for some queries I have to combine the third database with one of the other databases via attach statement to carry out complex queries.
On some devices, I'll occasionally get an exception that the database I'm attempting to attach to is already in use. To combat this, I added a synchronized function that closes the readable/writeable database instance of the database I'm attempting to attach to, and calling this before attaching to said database, but the error still crops up on some devices and the solution could obviously still have another thread re-open it before I attach to it anyway.
A nuclear option would be to create some master database class that has everything synchronized but I'd like to hear if anyone else has an architecture they've followed to combat this situation.

Is SQLite appropriate for off-line storage before replication to a server?

I am planning on writing an application that saves a fair amount of data. Historically, I have simply written data directly to a server, and only used some simple key/value storage with shared preferences for local storage.
I am considering this time, instead, using SQLite to save the information at first, and sync the data to the server in the background later. This will benefit the user in a few ways: 1) can use the app offline 2) don't have to worry about data being saved right away, it happens when ever it can 3) more reliability.
My approach will be to get/set data from SQLite during UI usage, and use a background process to find new rows and put them on the server, flagging them as synced when it happens.
Does this sound reasonable?
You can use SQLIte for your scenario. But, while implementing, you can follow any one of this approach.
Approach #1: Use an Abstract Factory to Instantiate the SQLiteOpenHelper.
Approach #2: Wrap the SQLiteDatabase in a ContentProvider
Refer to this link for how to implement these 2 approaches. http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html
Key points to be noted while using SQLite
Sqlite takes care of the file level locking.
Many threads can read,one can write. The locks prevent more than one
writing.
Android implements some java locking in SQLiteDatabase to help keep
things straight.
If we handle the database incorrectly from many threads and mess up the code, your
database will not be corrupted. Only few updates will be lost.
How "Multiple Threads - DB access" can be used for your scenario
The SqliteOpenHelper object holds on to one database connection.
If you try to write to the database from actual distinct connections (multiple threads) at the same time, one will fail. It will not wait till the first is done and then write. It will simply not write your change. Worse, if you don’t call the right version of insert/update on the SQLiteDatabase, you won’t get an exception. You’ll just get a message in your LogCat, and that will be it.
So recommended to write using single thread and read from multiple threads if necessary for faster access.
Does this sound reasonable?
Yes. Note that the synchronization process can get tricky (e.g., what happens if the server hiccups halfway through?), but that has mostly to do with synchronization and little to do with SQLite.
We implemented a solution that used a SQLite db on the device to sync data via a web service to the master database. We did this for a couple reasons: offline, poor connection, manual sync.
For our solution we had a flag on the table that determined if the data was pushed to the web service. Our web service also provided data back to our application to let us know if the data was received and processed correctly. This allowed us to clean up the data on the device, send notifications if there were failures, and resubmit the data if there were previous failures.
You can use push notifications as well if you have fixed the issues on the backend and have the device resend the data to the web service. This worked really well for us.

concurrent sqlite access in android application

My application has :
Activity A that reads from sqlite database
Service with notification that writes to the database
on clicking Notification, Activity A opens up
the reading by ActivityA is very small task(in reference to time taken to read)
but the writing by the service to the database is very long(it sometimes takes 5-10min)
now when the service is running and i click on the notification, ActivityA that has to read from the database cannot perform its reading as there is already a service writing to that database.
so activityA has to wait (for 5-10min) to read from database.
on researching further i came across this
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#beginTransactionNonExclusive()
when i try to implement this in my method inside sqliteopenhelper class i get error as my application uses min api 10. so how do i get this method working for api 10 or is there anyother way to have parallel database access
?
is there anyother way to have parallel database access ?
I think there is no special way how to achieve it. You should use classic Java synchronization for synchronized access to your database.
Most important thing is that you have to make sure you have only one connection to database (you can't write/read from two different connections in the same time). And try to think about an usage of Singleton. In this case (and also in others) it's very efficient and clean solution and you can avoid many problems with access to db.
You mentioned that your task can last 5-10 min.
In similar cases every user should know that you are performing some calculations in the background e.q. show some progressDialog, progressBar or simply start animation of image.
If you are showing some data for example in List this is good reason to use lazy loading.
Have look also at these articles:
Android Sqlite Locking
Using Singleton design pattern for SQLiteDatabase

Android SQLite : Lock + access from multiple threads

I am trying to understand the possible ways to work with SQLite when there can be multiple threads work on DB.
Based on various responses in stackoverflow and other sites, it appears that there will be locking issue when same sqlitehelper instance is used from multiple threads. In a typical java application, I would expect instance to mean single object of type sqlite helper to be used by different threads of application.In such cases, the locks ,I guess, are a matter of correctly using the synchronized blocks. [Correct me here as I am not comfortable with this way of looking at sqliethelper instance here]
My concern is with sharing same data base : when one instantiate sqlite helper in different threads [ie each thread has its own object instance] but working on same Database [this I guess is more inline with having same db instance].
In such cases I'm getting frequent database lock errors. This occurs even when the threads are working on different tables of database.
In my application database can be updated by user interaction through application or by getting data through server [periodic synchronization]. And some time when synchronization process and user activity overlaps, I get the lock issues. As this pattern of data processing seems to be common in application synchronizing with server, would like to know how do lock issue due the concurrency is to be handled.
I would like to understand this since if this is bound to happen always then probably need to make only one handler over database and implement queue over that to avoid lock. But that will mean the complete application needs to be aware that the database may not get updated immediately and they need to implement listener to know when the data is actually updated in database.
thanks
pradeep
As far as I know sqlite is intended for single process usage. No matter what you will always need to access the database from one thread at a time. You can do selects from multiple clients but can only write from one at a time. And other readers and writers will ahve to lock in the mean time.
As a side note - database access can hardly ever be considered instantaneous.

Android Database Insert At The Beginning

I want to insert required data for my application at the beginning and I will use these data. And I want to insert once, and there must be no duplicate. Therefore, in "onCreate", I'm doing like that : if the row count of table(such as student etc) is 0, I'm inserting students. I don't think it's the best way to do this. Therefore I want to learn if there is a better way.
If you want your database populated at install time and never any other time, your only reasonable option is to package your pre-populated database with your APK as a built-in resource. This has the advantage of simplifying your app.
Alternately, if you implement the SQLiteOpenHelper for your database, anything you insert during SQLiteOpenHelper.onCreate(SQLiteDatabase) will only ever be inserted either on the first run of you app or when someone clears all your app's data (which is more or less putting you back to a fresh install anyway). The SQLiteOpenHelper superclass knows whether or not to run the creation code when you call one of the getWritableDatabase() or getReadOnlyDatabase() methods to get your database reference.
It is worth noting that Android doesn't really let you run an installer the way desktop software does. If you need to do any setup work, you need to be able to detect and remember when your app has been run before.

Categories

Resources