So, after making all of my calculations an AsyncTask for my app and leaving the UI changes until the onPostExicute method I realized that my app gets a ANR from even just initializing all of the variables for my class which creates my AsyncTask. Here is the code I'm talking about:
http://pastebin.com/BB8M9afE
(the things in notes are pieces of code I'm playing with)
If you need more of the code, I can post it. How can I keep my threading class from causing an ANR?
Code Notes:
ColorFloodGame(6,6) fills an array of int's with math.random() values. GuiThreader creates a ColorFloodGame(6,6) and makes it an alias of the one in "Play" as well as creating a GUI driver which does the same
Use "adb shell cat /data/anr/traces.txt" to see the stack crawls of the last ANR. The first stack in the list is for the main thread of your app, so it shows what it was doing when the ANR happened. Look at where it was to determine what you are doing that takes so long.
Related
I don't get this, and it's really frustrating me.
All of my long-running operations happen in AsyncTasks. For example, the user interacts with the app somehow and an item is added to a list. This causes an AsyncTask to fire, the data to be written to an sqlite3 database, and then the list is refreshed.
I've recently bumped my Android support up from 2.3.3 to 4.0. I've created a new 4.0 emulator and, for some reason, all of my AsyncTasks seem to queue up and only fire once the user leaves the screen!
Why is this happening????
The code is pretty simple. I'm not doing anything interesting here. For example, here's an AsyncTask fire example:
Log log = data.mFoodLog;
log.setUserId(getUserId());
log.setDay(mBeginningOfToday.getTimeInMillis()/1000);
log.setStatus(DbDefinitions.STATE_POSTING);
(new SaveLogTask()).execute(new SaveObjectTaskParams(getApplicationContext(), log));
The debugger shows this code being executed. I have another breakpoint inside the doInBackground() method, but that breakpoint never gets hit until I leave the screen. I've also put Log.e messages around this code and ran it without the debugger to make sure the debugger isn't doing anything weird. doInBackground() never gets fired until I leave the Activity.
At first sight seems to be what #Cliffroot says, an async task not ending and queuing the ret of them (due to the behaviour changes in Android).
To execute them on diferent threads use: asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
Basically the behaviour of AsyncTask has changed since version 3.0. On 2.3.3 it used to execute AsyncTasks concurrently, but now it does it sequentially.
So your problem might be that you have one AsyncTask that does not finish, and because of that fact the others don't even start (it's hard to say without seeing more of your code).
In the app I have an activity which has launch mode as singleTask. There are number of use cases which pass through this activity and hence it's called number of times. On stress testing the app by running monkeyrunner script and calling this activity every few seconds causes ANR's.
I guess, the way it's designed where most of the use cases pass through this activity is not correct but I am not in a position to change this design.
Is there anyway ANR's can be suppressed? I mean, adding UI operations to event queue so that it doesn't block main UI thread and doesn't give ANR.
It is unclear from the question what your activity is (or should be) doing. Probably you need a service instead.
It is common to perform time-consuming operations in background threads and deliver the results to the UI thread.
You may use the classes Handler/Looper (it it easir to send Runnables rather than messages), or use an AsyncTask. The AsyncTask is nevertheless tricky, this is discussed here: Is AsyncTask really conceptually flawed or am I just missing something? . AFAIK Google tried to fix the typical bugs and made the new behavior incompatible with the old one (namely, I have seen some misbehavior on the newer Androids that may be explained by the assumption that since some version threads doing asynctask jobs get killed after the activity that started them goes out of the screen).
I can guess that singleTask is your way to fight the fact that an activity dies when the screen turns, and a new one comes. I suggest you use singletons (they survive screen rotation but do not survive a process restart, one more thing that sometimes happens in Android). (The user switches to an app like Camera, takes a big photo, returns back -- and the activity is restarted because Camera needed memory. Have seen this in practice, but that time I did not try to find out if the whole process was restarted.)
Anyway, please add logging telling you when your activity in entered and left, including onNewIntent() and other lifecycle functions (to be on the safe side, I recommend to print the thread names as well). Then you will probably see what is going on.
I'm using an app that uses async tasks to do short term background calculation jobs. These seem to end OK (go through onPostExecute() etc), but in the Eclipse debugger, one or more still hangs around.
Then I found this link - AsyncTask threads never die - so OK, it's about a thread pool and in theory not an issue.
Problems is however, I am also trying to use Google in-app billing code V3, and that appears to throw an exception whenever you carry out a purchase and there's already an AsyncTask thread hanging around. Catching the exception won't help - it still won't do anything.
How can I get around this? What do I need to do to guarantee the old calculation thread(s) have gone?
Found out what is going on here, and it wasn't what I thought. I'll detail it here as it may be useful to somebody. Has nothing to do with other AsyncTask threads and thread pooling.
In the IabHelper class are two functions flagStartAsync() and flagEndAsync(). The aim of these is to produce a single pass gate (bit like wait() and signal() in traditional multi-threading) so only one async operation (that is, communications with Google Play and the server) can occur at a time. If flagStartAsync() get called while something is already going on, it produces an exception. Not terribly graceful, but effective I guess.
The flagStartAsync() 'test and set' gets called at the start of launchPurchaseFlow() among other places, and flagEndAsync gets called in handleActivityResult() - again - among other places. So providing the purchase flow does something that always produces a result, no problem. The problem is - it doesn't always.
If you look at launchPurchaseFlow() there are several paths out that will not kick off the async operation, and if one of those get taken, mAsyncInProgress (the relevant flag) gets left set.
What blew it in my case was that I hadn't checked that the item was already purchased, and 'already purchased' is one of the paths out. Mea culpa, but the problem is that I cannot convince myself that there aren't several other paths that you just cannot avoid at times. What if operation is slow and the 'purchase' button gets pressed twice, for instance? I bet there are others as well. One could catch the exception, and that would stop a crash, but it wouldn't really help if nothing came along to clear the flag in the end. I guess the exception handler could call flagEndAsync() but it has an uncomfortable 'sledgehammer to crack a nut' feel.
It strikes me that this is probably a non-robust piece of code. What I've done for now is call flagEndAsync() in the various ways out of launchPurchaseFlow(), but that is just a temporary fix. I don't know enough about the IabHelper code, but I think it needs more careful thought and I need to analyse it to see everything it does.
I have an application, where we are providing the Remote UI(which contains all the buttons to control the Media server).
The problem is when we click any of the button, we are executing the corresponding action, which is very long UPNP network operation.
so when we press the buttons continuously , finally the device comes up with ANR Exception and force close the application. I made some research on this ANR Exception and finally found that, we can use Thread or AsyncTask to solve this problem.
But in my application since we are providing so many buttons, when user presses buttons continuously , it may inturn lead to lot of threads created in the application.
Please give me your suggestions on this.
How to overcome this problem?
Thanks
One of the many advantages of using AsyncTask is that it manages the threading (and thread pooling) for you. So if you use AsyncTask, you shouldn't have the problem of creating too many threads.
In addition, if you're concerned with creating too many AsyncTasks, consider putting the tasks in a member variable (such as a Queue or ArrayList) and keeping track of their state. If one is still processing it might not be necessary to start another. Or you can remove tasks whose results are no longer needed.
Just keeping track of the button click in member variable and using One AsyncTask you can perform this long running operation in queue wise.
If possible just avoid multi-threads for these operations.
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