I am currently compiling and executing some C++ code on a rooted Android device. I use adb (adb shell). To compile my code, I don't use the NDK, but I cross-compile with CMake
I'm using the function sleep(seconds) of unistd.h.
I've experienced some curious behaviors with that function on Android: Basically, I have a for loop in which I std::cout something and then call sleep(x).
If I call sleep(1), the behavior is the one expected: The program waits 1 second, and then executes the next instructions.
If I call sleep(2), the behavior isn't the one expected. The program gets stuck on that instruction for ever.... until I hit a key on my PC keyboard (not the device's one), and then it gets stuck on the next sleep(2)... until I hit a key, etc...
This behavior happens only when the device screen is off. As soon as I click on the power button to turn the screen on, the program resumes and has the expected behavior.
N.B: The behavior is the same with usleep(useconds)
I have tried to see where the limit is between 1 and 2 seconds:
1.5s, 1.25s, 1.125s -> always stay blocked | 1.0625s -> ~50% chance of staying blocked.
Obviously, there is something that prevents a thread to wake up if it sleeps more than 1 seconds (at least 2).
So my question would be, does anyone have any idea of why this is happening, and has a detailed explanation of the process ?
Thank you !
Android puts applications in the background when they aren't doing any user interaction - unix sleep and java timers etc. won't wake them up. You have to use an android alarm or runnable postDelayed handler.
Related
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).
In Eclipse, I load up an Android Virtual Device, and then once it's loaded and not at the lock screen, I hit "Debug" on the Eclipse toolbar. My app runs fine (barring any errors from the last edit cycle, but that's what debugging is for). However, after I try to end my app (by hitting the back button from the main [only] activity - I have implemented a call to finish() as the last line of onBackPressed() , even though on further research it appears that hitting the back button from the main activity implicitly calls finish() ), it appears to not end the app.
The Eclipse debug perspective's Debug pane still shows the following:
MyAppName [Android application]
DalvikVM[localhost:8619]
Thread [<1> main] (Running)
Thread [<10> Binder_2] (Running)
Thread [<9> Binder_1] (Running)
I am assuming the DalvikVM line is the emulator. I do not knowingly spin up any extra threads in my app (light enough computations, so far, that I just do them all in the UI thread on button clicks, etc), so I have no idea whatsoever where Binder_1 and Binder_2 came from.
Also, when I go to debug again, thinking the app was fully shut down, the tool-tip on the debug icon is "Debug MyAppName (already running)".
Does finish() not terminate the application when it comes to Eclipse's debug hooks? Or, is there some other method I should call from the main activity that behaves like a "terminate()", that tells Android that not only the activity, but the whole app, is finished?
Yes, I am aware that Android apps' processes are not immediately killed when running on the device during the normal life cycle. I realize that I don't want to make my app kill its process stone cold dead when it comes to the shipped version. However, if this is the cause of the persistent debugger tie-in, I would at least like to implement something like if(DEBUG_MODE) trulyExit(); , either by teaching Eclipse to autokill after a finish() somehow, or by implementing some sort of trulyExit() in my main activity, to only be used during debugging. So, if I could get a few tips on how to teach Eclipse, or how one would implement a trulyExit(), that'd be awesome.
My workaround currently is closing the emulator each time. I can't think, though, that that's how you're supposed to end a debugging session...
Relevant dev environment info:
(OS: Windows 7 Professional)
IDE: Android Developer Tools build v22.0.1-685705
No additions/plugins to the ADT Eclipse, other than what Google's ADT download gives.
Test platform: Emulator, not device
(the USB port on my physical device is on the fritz, I am not sure if debugging tie-ins will still misbehave on it or not.)
I recently began writing a phonegap android application and noticed that when the app is resumed from the background (so I deploy the app to an android tablet, press the home button and then reopen the app from the menu) it gives a timeout error (something to the effect of Error code =-6 The connection to the server was unsuccessful) and then crashes. From what I've tested this only seems to happen when the "Don't keep activities" option is checked in the developer options, when that option is not checked the app works as intended.
It's also worth noting that I recreated the default phonegap application, ran it and encountered the same issue.
Can anyone explain why this happens, or suggest a solution? Obviously I can get around this problem by simply leaving the Don't keep activities option unchecked, but I'm guessing the problem will persist on any android device that has this option checked, which just won't do.
I'm using phonegap 2.5.0 and testing on a device running Android 4.0.3,
Thanks,
Josh
"Don't keep activities" is a developer tool to simulate user activity that would be extremely hard to test for. I personally believe all apps should be tested a second time (at least run automated tests) with this setting turned on, and devs should turn it on / off during development.
Your issue (which I've just ran into on v2.7) comes from a silly implementation of a timeout feature. CordovaWebView.loadUrlIntoView creates and locks (wait()) a thread for 20 seconds (default value), after which time it checks a value to see if the url finished loading - if it hasn't finished, it shows an error message.
This thread exists outside of the lifetime of your activity, so if the activity stops running, the Webview can never finish loading the url, and when the thread wakes up, it does Bad Things trying to show the error.
The same crash could happen without using "Don't keep activities" by simply having the user leave the application and then the system reclaiming the activity's resources (because it is low on memory or something) within 20 seconds.
Using a Handler seems like a more appropriate way to handle this timeout, but without changing the source there are a couple of hacky work arounds.
Call System.exit(0) at the end of your Activity.onDestroy() - this is horrible, but if you only have the one activity and no services, it might be an option
Use reflection to change CordovaWebView.loadUrlTimeout - this is horrible, but it should work, this is the value that the thread checks to see if the url loaded (inc by 1).
On Android 2.3.1, when you use the trigger.io code below, the trigger framework doesn't scan the bar-code the first time when it is invoked. Actually the camera opens and the bar-code is scanned, however, after the scanning is complete you see the trigger splash page and the success function doesn't get invoked. It starts working like it should when the scan function is called from the second time on-wards.
forge.barcode.scan(function (value) {
alert("You scanned: "+value);
});
This sounds like the app is being forcefully closed when the camera is started, due to device resource constraints.
If you look at the output of "adb logcat" in a terminal, you'll probably see a message about an unhandled intent.
In this case, there's not too much we can do - the Android OS has started killing processes to free up memory. We always keep our wrapper as lightweight as possible, and will continue to look for areas to increase efficiency.
We have only seen this problem occur with any regularity on low-spec devices running later versions of Android. If it's happening a lot for you, check your app's not leaking memory - again, the output of "adb logcat" can show GC activity.
I am working on a strange issue with the i2c-omap driver. I am not sure if the problem happens at other time or not, but it happens around 5% of the time I tried to power off the system.
During system power off, I write to some registers in the PMIC via I2C. In i2c-omap.c, I can see that the calling thread is waiting on wait_for_completion_timeout with a timeout value set to 1 second. And I can see the IRQ called "complete" (I added printk AFTER "complete"). However, after "complete" gets called, the wait_for_completion_timeout did not return. Instead, it takes up to 5 MINUTES before it returns. And the return value of wait_for_completion_timeout is positive indicating that there is no timeout. And the whole I2C transaction was successful.
In the meantime, I can see printk messages from other drivers. And the serial console still works. It is on Android, and if I use "top" I can see system_server is taking about 95% of the CPU. Killing system_server can make the wait_for_completion_timeout return immediately.
So my question is what could a user space app (system_server) do to make a kernel "wait_for_completion_timeout" not being wake up?
Thanks!
wait_for_completion_timeout only guarantees that the thread waiting on a condition would become "runnable" when either (i) completion happens or (ii) timeout expires.
After that it's the job of scheduler to schedule that thread and change it's state from "runnable" to "running". The thread itself(or the completion framework) is not responsible to make a thread runnable, that's the job of scheduler.
As you have pointed out, system_server is consuming 95% of cpu and therefore making it hard for the completion thread to get scheduled. That explains why the thread is not getting scheduled.
Well, I kind of figured it out.
In the CFS scheduling, in enqueue_entity, it does "vruntime += min_vruntime" in some condition, and in dequeue_entity it does the opposite under some condition. However, those are not always executed in pair. So under some unknown condition, when min_vruntime is pretty big, the vruntime can get pretty big, so the task would be put to the right side of the rbtree and not get scheduled for a long time.
I am not sure what is the best way to fix this from the root cause, what I did is a hack in enqueue_entity, if I found vruntime>min_vruntime and the function is called for WAKEUP, I always set vruntime=min_vruntime, thus the task would be put to the relatively left side of the rbtree.
The kernel version I am using is 2.6.37
Anyone has a suggestion on how this should be fixed in a better way?