Is context switching using up significant time? - android

I have been having problem with an app (which uses both java and C++ and OpenCV) which appears to be very inconsistent in the amount of time it takes to perform various tasks. To help diagnose this, I made a function in java (called one_off_speed_test()) which did nothing but a series of integer maths problems in a loop that takes about half a second, and then prints the time taken to the log. If I call this function repeatedly from within onCreate() then the time taken for each call is very consistent (+= 3%), but if I call it from within onCameraFrame(), a function that OpenCV calls when it has an image ready from the camera, then the time taken for the maths test in each fram varies by anything up to a factor of two. I decided to try the execution sampler in eclipse/DDMS and see if I could work out what was happening. I saw that when I clicked on one_off_speed_test(), it listed the parents and children of that function, along with a line saying "(context switch)". Then on that row, under a column labelled "Incl Real Time", it says "66%". Now I'm not very expert in using DDMS, and I only have a hazy idea about context switching, but from the description so far, does it look like I have a problem with context switching taking up a lot of time? Or am I misunderstanding the DDMS output.

Context switch describes the time spent to execute other threads. So, when your function is called from onCameraFrame(), it shares CPU with other threads, not necessarily threads that belong to your app.
See also answers https://stackoverflow.com/a/10969757/192373, https://stackoverflow.com/a/17902682/192373
In the posted example, onCameraFrame() spent 14.413665 sec on the wall clock, of which 4.814454 sec was used by one_off_speed_test() (presumably, for 10 frames), and 9.596984 sec was spent waiting for other threads. This makes sense, because onCameraFrame() callback competes for the CPU resource with the camera service, which runs in a separate system process.

Related

Why Robo tests gets marked as passed so quickly?

TL;DR
The app has tons of flows, but sometimes runs get passed faster than 2 mins...
Is there any way to keep it running until the timeout period (e.g. 1hr) is almost consumed? Attached a screenshot for a quick termination e.g.
Although the app is very big with tons of flows, sometimes runs get passed after 2min, 5mins but what is the critieria which decides that the running robo test should terminate now with a passed result? any idea what makes the recorded graph decides to go to this node? n.b. I assumed it's the terminal node
Why Robo tests get marked as passed so quickly?
It turns out that due to having a varying b.e. responses, the app journey gets changed. If there're 3 disconnected components (as in gif), what happens is sth like the app can start in any of the 3 flows resembling the 3 components. Which implies how long the journey will be
Is there any way to keep it running until the timeout period (e.g. 1hr) is almost consumed
Guiding the robo tests as explained here is a promising way to let journey bigger by following some sequence of actions which make the graph bigger
What is the criteria which decides that the running robo test should terminate now with a passed result?
Robo tests are simply applying flood fill on the app (as in gif). Where the graph nodes are represented by screens, e.g. onboarding screen, and edges are represented by actions, e.g. click on next button
Most likely it is always more or less the same time duration ...while the only difference may be the test's position in the queue (you're not the only user there, which is why it may appear as if the duration would vary). And that TerminatedActivity-33 only confirms that the Activity under test had been successfully terminated ...which is "The End" of the story.
For reasons of efficiency, the test will terminate as soon as possible - the timeout value can only be reached when it's stuck.
That the queue may also run in parallel might be another possible cause; while then, even if the real-time duration would indeed vary, the processing time (CPU shares) would still be about the same. Disclaimer: I have no clue how it internally works, just tried to apply some common sense.

Android app dies with "Launch timeout has expired, giving up wake lock!" on certain phones

I am working on an Android app that displays a continuous custom-rendered animation on the title screen and thus doesn't really enter the idle state when it's done loading. On most devices I've tested, everything runs fine, but Samsung's Galaxy S2 kills the app after a few seconds. I don't get a stack trace or any output of the System.out output that I put into the onPause event handler and the default uncaught exception handler, so it doesn't seem to be a normal exit or an Exception in my code.
The only output I get in LogCat is the following:
Launch timeout has expired, giving up wake lock!
Sending signal. PID: 22344 SIG: 3
handleActivityTimeout pid=[22344] cnt=10
Process ... (pid 22344) has died.
There are several related posts here on SO (1, 2, 3, 4), but they all seem to trigger the issue slightly differently (alarm, recursive loops, network requests in the UI thread, ...). The last one links to a Google Groups discussion that says that this error message can simply be ignored. An approach I'd rather not take since it causes my app to actually crash on the Galaxy S2 (and maybe others?).
Basically what I did was to write a custom View that renders the next animation-frame in its onDraw() method and then calls postInvalidate() right before returning from onDraw(). In case it matters: My first postInvalidate() call happens during onCreate(...).
The rendering is very quick and runs at 40+ frames per second on that device and well over 60 fps on more modern phones. So control goes back to the event loop very frequently and the app is also very responsive. Yet, the Galaxy seems to think that it has crashed and kills it (if that is even the reason for my app dying there). The thing is: If I am quick enough to click on a menu-item in my app to end up on a screen without an animation to break out of the "tail-recursive" postInvalidate() once, everything runs fine. Even if I then go back to the title screen for a long time where the animation runs again.
So, of course, I could probably just use postInvalidateDelayed(...) once to break out of the start-up check, but that seems like a bit of a hacky solution and I don't know if there might be any other devices out there that might consider my app dead at a later stage (not just during start-up) and kill it.
Is there something fundamentally wrong with using postInvalidate() in the way I'm doing? Is there a way to fix it? I would like to avoid having to move to a separate thread since that opens a whole other can of worms as far as passing events back and forth between the UI and that thread. I know it wouldn't be the end of the world and using a SurfaceView, it might even lead to a slight performance improvement, but it's really just not necessary from a user experience point of view (everything runs perfectly smooth), so I'd like to avoid the involved additional opportunities for issues (multi-threading is notoriously difficult to debug).

AsyncTask thread never ends

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.

Traceview profile: Handler.dispatchMessage using significant CPU time

I've just started to profile my app at its prototype stage using Traceview.
I've found that the main user of cpu time (90%) is Handler.dispatchMessage. The main user of real time resource (50% combined) is MessageQueue.next and MessageQueue.nativePollOnce. Calls made by my own methods account for, on average, 2% of real time resource each.
Currently, whilst I am still developing the app I have toasts that appear when there is interaction with my service. I am assuming (about to test the theory tonight) that these calls are down to my frequent use of Toast. Is this correct?
Since Toasts appear on top of the activity whilst you are still using it, having its usage appear in Traceview is a bit deceiving. Is there a way to filter out certain method calls in Traceview, or will I just have to comment the Toast calls in my code, re-build, and re-test? I suppose using a SharedPreference to set whether to use Toasts or not might be useful.
Thanks for the help.

Android's best approach for precise timed events handling

I´m trying to improve my events handling system to make it more robust, improving precision stability.
Since the it´s a time based event handling/answering system, the first relevant decision would be which time reference to use. After reading everything I could find I ended up using SystemClock.elapsedRealtime().
Why not to use SystemClock.uptimeMillis() or System.nanoTime()? Because my system needs to keep working while in sleep/screen is off.
Any better approach here?
After that, the most problematic step: how to handle the timed events and guarantee they happen at desired time, without lags/delays/variations?
After reading as much as I could I decided to go for the handler approach, having one of them for each class of event (so different classes can happen asynchronously).
Unfortunately this isn´t working as expected:
- The timming sometimes gets perfectly synchonized and sometimes gets really big constant delays. without changing the code at all, just launching the application minutes after. Any clock synchronization issues between threads (event generator and event handler are in different threads)?
- The handler timming isn´t constant/precise and I can easely notice event results being displayed out of sync with a variable lag.
Any tips about how to handle timed events in a more precise way in Android?
Thanks,
Gabriel Simões

Categories

Resources