My program involves interaction with SQLite in a fairly regular basis, and in the beginning of the app, I call a query
mDatabase.rawQuery("SELECT key,
indice as _id
FROM Dictionary",null);
Strangely the app stalls on executing this line. This does not happen if I am debugging the application, but when I run the app, the control goes from this line and never returns. I have checked this by putting logcat before and after this line.
I have not been able to comprehend this behavior. Can someone help?
P.S. The table Dictionary has over 2000-3000 records.
EDIT:
I have tried calling this from both UI & separate threads. Either ways, the execution stops at this call (for that thread). So when I call it from another thread, though there is no ANR, the call still fails and holds the thread indefinitely.
EDIT2:
This issue does not happen every time I run the application but 5 out of 10 times. And apparently happens more on weaker phones.
Take care of below points.
Make call to query in separate thread other than UI thread.
Cursor at max can hold upto 1MB of data. So query for minimum amount of data.
You should take this off the UI thread. Looks like a heavy call. Anything which takes longer than 5 seconds and stalls the UI thread will trigger an ANR.
Yes piyushnp and abhinav are right. AsyncTask or Thread are better option for getting the details. Show progressbar when doing background processing. And when you get query results display it in activity or do whatver processing you want on query results.
This example simulates your problem. AsyncTask basic Example : AsyncTask
Related
My app has a pretty big database, especially one of the tables - it has like 2 million entities. In the next app release we are doing a huge update - dropping one of the columns and replacing it with another one. For the biggest table this takes ~ 13 sec.
The problem is even though i have put this update in a background thread(still it is in the onUpgrade method of the SQLLiteDatabase), it still blocks the UI thread and causes an android os popup to appear - prompting to either kill the app or wait.
Is the onUpgrade method actually blocking the UI thread, or am I doing something wrong?
Use StrictMode API to detect the exact cause of the UI thread blocking.
I would recommend you to a service and initiate this db upgrade if it's going to be huge one, also provide a loading screen if you don't want see the UI immediately.
Hope this helps.
There was actually another database process that was blocking the UI thread. I managed to identify the problem using the StrictMode API. Thanks #albeee
I have a lot of data that is stored in a CSV file (about 20,100 rows), which I need to insert into a sqlite database.
This insert is taking very long to complete. What is the fastest way to insert this data?
As you have suggested, number of rows are huge I will recommend not to use AsyncTask, as its not tied to your Activity lifecycle i.e if you activity which started it dies, it doesnt mean AsyncTask dies as well, so if you try initiate a AsyncTask and somehow if your activity dies e.g screen rotation or back key pressed, upon restarting another AsyncTask will get spawned rather then it getting linked to already executing AsyncTask. hence duplicating same operations.
So, all in all I would recommend following approach
(A)
Create a IntentService, it's handleIntent() api already executes in a worker thread so you don't have to worry about any thing, and once all messaged in its queue are finished it automatically dies, so no worry at all about leaking any resources.
write your logic for inserting rows in bulk, use content resolver bulkInsert() api for same. I will recommend inserting in 100 roes per batch, you can implement rollback and error checks to make sure insert goes normally.
Once all insert is finish, you can post back to your UI using Handler and Messengers.
with all this you will achieve two major challenge
Not to hang up your UI, escaping any possible ANR
Even if back key is pressed, ensured that db operation goes on smoothly as it was taken up in background task.
Using AsyncTask<>, insert 20,100 rows inserts in database. Using this asynctask whole work run in background. For more information follow this link
The best solution would be using services and executor because as OP described, process can take a lot time. Thanks that You will be able to close app or move it to background with no worried Your long process is destroyed.
Using AsyncTask is not a good idea because it was designed for short operations as it is described on http://developer.android.com/reference/android/os/AsyncTask.html You must also be careful with using it. Changing orientation screen cause recreating view and also task of asynctask.
AsyncTasks should ideally be used for short operations (a few seconds
at the most.) If you need to keep threads running for long periods of
time, it is highly recommended you use the various APIs provided by
the java.util.concurrent package such as Executor, ThreadPoolExecutor
and FutureTask.
I have the following problem. I'm working on a mobile solution that consumes data from a server. For thoses HTTP transactions I obviously use an AsyncTask in order to separate this communication task from the main thread. However, after a successful response I need to build a Really Big Table Layout (with 2000 - 10000 table rows or more) to insert all the records coming inside the data. So if I start to build the table in the main thread I'll always get a ANR problem (Application Not Responding Dialog).
On the other hand, it's widely known that I cannot modify/add/touch elements from a different thread that is not the UI thread, so I have not been able to do this heavy table processing.
Suggesstions are heard. Thanks in advance.
You can archive it with pagination, you can show 20 rows first, when you scroll down and reach the bottom, add the other block of 20 elements and so on.
Why not just use the onPostExecute method of your AsyncTask to accomplish this? You can do all of the heavy processing in doInBackground, and then when you are done, simply update the UI in onPostExecute, which runs on the UI Thread. You can find more information on AsyncTask here: http://developer.android.com/reference/android/os/AsyncTask.html
In my app, I have a ViewPager with +/- 10 pages. When the app is first opened, all the pages are instantiated and immediately begin to load data to display. Each page (which are fragments) creates an AsyncTask to query a database and populate itself with the appropriate data. Here's the problem: even though the work is being done on separate threads, the UI stops updating during the database queries (which are done sequentially, and take 1-3 seconds total). This happens both on my Nexus 5 and a crappy old Samsung phone, so I know the problem is not that the hardware just can't keep up.
So ultimately, I'm wondering why the UI thread is blocked by work done on a background thread. My understanding of threading was that doing work on one would not block the other for an extended period of time. If my understanding is wrong, please explain how. Thanks in advance.
I don't think code is required here, but if it is, let me know and I will post the relevant portions.
It stops animating immediately after the first database query begins and starts animating again immediately after the last database query completes
It is possible, then, you are not doing the work on a background thread that you think you are. You may be doing the work on the main application thread.
Traceview can help you identify what you are doing on the various threads, and StrictMode can help you with obvious problems (disk I/O and network I/O on the main application thread).
In this case, you may be getting caught by how you are doing your work:
Each page (which are fragments) creates an AsyncTask to query a database and populate itself with the appropriate data.
If you are doing your query in doInBackground() but are not touching the resulting Cursor also in doInBackground(), the query actually wasn't done yet. The Cursor is a SQLiteCursor, and it lazy-executes the query when the data is first used. This is another one of those "really cool ideas that just plain suck in how we do things nowadays". A workaround is to call getCount() on the Cursor while you are in doInBackground(), to ensure that the query actually is executed on the background thread.
Here is the case:
In my app, I have service which is used for communication with other special device. In the middle of this communictation I need to query database in my app to get data neccesary to proceed communicating with 2nd device. Here I am using rawQuery with 2 parameters. Query is a not too complicated cause I am actually quering view in database. As a result I should get back around 50 rows and 25 columns.
The thing is that if I just call this query from service (same thread) it blocks my UI for like 6 seconds. There is animation signaling long operation which got stuck.
On the other side, if I call exactly same query in doInBackground of AsyncTask (to move it from UI thread) my animation flows without troubles but for same amount of data query now need 25 seconds til 1 minute depending on which phone I am testing.. (almost 1min take on new Motorola with Intel cpu)
I measure times and where is so much time lost (cause queries and databases are exactly the same on both phones) and all this time is wasted on first access to cursor. In my case c.moveToFirst() ..
My question is more Android oriented not SQL, cause in my app I integrate already complete, filled with data, database
Any idea, anybody?
Edit: I try different solutions for issue I have and here is interesting thing I came to: When I use another thread with Runnable which has query, time is reduced back to few seconds (exactly like everything is executed in UI thread)
Thread t = new Thread(RunnableWhichHoldQuery); //then I just start thread t.
Still not sure why AsyncTask is behaving like it does.. Now I am just curious for explanation cause I would like to understand better what is going on.. thanks to everybody with ideas..