Android service and main thread CPU usage - android

In Android, is the main thread favored in the use of the CPU, compared to Service? If yes, can I give, for a certain period, the complete control of CPU to android service? Or more generally give different priority?

If your question is related to the problems with db access, you should revisit your db access patterns, because that's where your problem lies. Otherwise, you may play with priorities and processor affinities and services and all this stuff, make the system unresponsive and eat the battery in an hour as a result, and still get the db access problems.
When there's a service with a need of constant RW access to the db, and you try to open the same db from another place, it would most definitely fail. Therefore, don't try to access db in onClick(), but have your service to prepare the necessary data and save it somewhere to be loaded when button is clicked without accessing the db.
Sorry, could not tell you more unless you explain the details of what kind of data you use and how you want to process it.

Related

Android best design practice for accessing SQLiteDatabase

In my Android app, I have a local DB (SQLite) that the app needs to query for data. The query may take a long time (>5 seconds) so I am avoiding using the main UI thread for that. The returned data may also be rather large (> 1 MB).
Between AsyncTasks, Threads, ExecutorService, and IntentService, (and maybe more) what's the best class/API to use in Android to do this? Are they all more or less the same in terms of what they offer? Or is there a clear winner and a better suited class for database access?
The answer, I'm sure you can predict, is "it depends".
If you are writing a set of related calls (for example that will sync your database using an API), then I would want to use an IntentService since it's a long running operation not directly tied to your user interface.
If it's a one-time operation hitting the database to get a result set, I would lean towards the loader framework/CursorLoader to fetch data for your UI. AsyncTask is an option, although it's really a more general purpose threading mechanism. Also, consider an ORM framework that does threading work or maintains a queue of work items for you.
I can't really think of a case where managing a Thread directly would be the best option. It's very low level and lots of room for error when there are nicer abstractions over it.

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.

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.

Database handling with 2 processes

I have a an application that has 2 parts.
A service which creates content.
An application that uses the content
Each of these run as different processes. The problem is that both of them share a database. And I frequently get database locked error, both when the service tries to write something and the UI is reading data. Also vice versa.
How do go about this?
The class used to access DB is a singleton class. But since both UI & the service are 2 different processes, there are 2 singletons I presume. So that doesn't help.
Even synchronise won't help I suppose, since again because of 2 different processes.
Content Providers maybe an option, but since I use complex queries to dig info, it would be really hard to use that too.
How do I get the two processes share the database.
Any cues would be greatly appreciated.
Using a content provider is one option. Another is to take a look at Berkeley DB. The BDB SQL API is SQLite compatible and the BDB lock manager allows multiple threads and/or processes to read/write to the database concurrently.
close the connection after each operation
catch the database locked error and try to reconnect after 50ms
or let the service handle the database and the activity ask the service for data
may be there is isDatabaseInUseMethod ?
You should use a content provider to funnel your database queries through one source. Inside of the content provider you can use any locking mechanisms you would like to ensure you're not having concurrent access. You may also think about using content observers to coordinate service actions with changes to the database.
The following is a great article on how locking works with SQLite on Android and what things to be aware of: http://kagii.squarespace.com/journal/2010/9/10/android-sqlite-locking.html
I would think you'll find some answers there :)

Android: can't decide how to manage background task

I have a task which I need to run in the background in my Android app. It reads data over the network and populates a database. It can take several minutes to run.
Once it's started, it needs to complete successfully without interruption. (Otherwise I'll end up with a broken half-populated database.) I realise I can never guarantee it will always complete, but I want to make it as hard as possible for the system to kill off this task. For safety I guess I will have it populate a temporary database, and then only swap out the old database for the new one on successful completion of the import.
It's a modal operation; it does not make sense for the user to be interacting with the app while the import is in progress.
My first attempt is using an ASyncTask with a Progress dialog to achieve the modality, but this obviously breaks the "don't interrupt" requirement. I could work around the screen-rotation issue with ASyncTasks, but I don't think that goes far enough.
At the moment I'm not sure if this should be an ASyncTask, a Service, an IntentService, some combination of these, or something else entirely. Can you help me decide?
I'd run it as a service and additionally I'd also have a clean SQLite DB on my server populated with the data the clients are going to retrieve so I can generate a kind of signature. Have the clients check for the correct signature of the DB. If the signature is not matching the servers signature then reinitialize the database filling process.
This is just an idea tho. I have no idea whether it'd be possible with what you are trying to do or not.
You are better off with services in that case. The Android runtime will leave it alone working as long as enough memory is available. In the case it kills the service, you can save the state in a bundle, and the system will restart the process as soon as possible, so you can resume the process, if possible for your solution:
Android Fundamentals, Service Section
Then it is easy to communicate with the service, like showing the progress/ notifications etc, using a handle registry like proposes by Mark Bredy in his Android Service Prototype

Categories

Resources