I am developing an Android app that is causing the OS to Freeze.
My question is rather simple but after lengthy searches I have come no closer to an answer.
The question is, how can an app which is sandboxed, cause the entire Android OS (4.0.4, 4.1.1, 4.1.2) to freeze?
Specifically, the entire OS freezes. No logcat, no adb, nothing! It is as frozen as an OS can get. The device is a Samsung Galaxy Tab 2. The app uses the UsbManager and the library from the usb-serial-for-android project. While the library may use the NDK, my app does not. Essentially, the app communicates serially with a propriety board, receiving data and sending serial commands. This is done on a worker thread that is disposed of in this manner:
try {
thread.interrupt();
thread.join();
while(thread.getState() != Thread.State.TERMINATED){
// wait until thread finishes
}
} catch (InterruptedException e) {
e.printStackTrace();
}
It all works fine, that is until the freeze occurs - when I disconnect the usb cable or instruct the library object to disconnect. Either way, the entire OS gets unstable and will freeze immediately or upon connecting the usb again (board or computer). I have posted this freeze issue to the usb-serial-for-android project but have not received any comments yet. I believe I am following the proper protocols when disengaging the usb.
I understand many things can go wrong - my app can crash et. al. But again how does a sandboxed app crash the OS - it does not seem to be very sandboxed if it can do that.
UPDATE
I have after much experimentation found that by removing the thread.interrupt(); line that it works without crashing the app or freezing the OS. It still freezes the OS if the USB is unplugged without first dismounting it.
I still desire to understand how a sandboxed app can freeze the entire OS though. There are comments here that elude to an answer, but are not an answer alone.
Where is your code sample above located?
It should be be on a UI thread, potentially blocking user interaction.
Are you also getting ANR messages before the freeze?
thread.join();
will block indefinitely. See Thread.join() documentation.
Also, the following looks like a busy loop to me.
What are you doing at the comment? If nothing, then the loop will spin like crazy (think while (true) { }).
while(thread.getState() != Thread.State.TERMINATED){
// wait until thread finishes
}
Related
My test suite runs fine on iOS, the app has many background processes running that prevent large portions of the tests from working in synchronized mode. The desynced commands run properly on the iOS simulator, but when I run them on the android emulator it is as if I never called await device.disableSynchronization().
The tests still hang and the console logs:
The app is busy, due to:
- Enqueued timers
- Animations running on screen
Any ideas about how to fix this?
Further review shows the error message:
The app has not responded to the network requests below:
The odd thing is the listed network request has been completed. The request upon which the app purportedly has not responded is a button push that navigates to a new screen which incurs a somewhat lengthy network request. After the network request completes other processes continually run necessitating the disabled synchronization. Since Detox is still waiting on some response from the app about the button tap, it does not move on to the next, desynchronized, actions. Is there any way to ensure that Detox receives the response of this .tap()?
A deeper investigation reveals that this is likely caused by a lingering animation that, for whatever reason device.disablesynchronization() ignores on Android builds. I am now working on mocking this file based on the out-of-date documentation provided by wix.
I am developing a VoIP based application which is multithreaded. For every socket there is a c++11 std::thread (including SSL read & write). The core module for data communication is in C++ which is called through JNI interface.
My observation is that, once initializing the application after few seconds, some threads which were running earlier normally are not getting running time. If a certain thread is running then it keeps running for a while ranging from 3-4 seconds to 30-40 seconds.
After referring change native thread priority on Android, I also tried changing "nice" value to -10 for all the threads, but no luck.
Important to note that exactly same C++ code is working perfectly fine for iOS.
Is there an issue with Android Native thread scheduling, or am I missing something?
while (...) {
int selectResult = select( fd, ...);
if ( selectResult > 0 ) DoSomeWork( fd );
else nanosleep(...); /* this is the new line which solved my stalling threads */
}
I had a similar problem, and found that for my case the solution was to verify that those threads that have an eternal loop (constantly performing select until there is something on a socket to spawn a handler thread), always call nanosleep at least once in their loop.
Like you, I experienced this issue on Android, and no issue on iOS.
I can only hypothesise that the JVM on Android sometimes would give full priority to one thread which is only polling a socket without pausing, such that other threads which had actual work to be done would stall. But I wouldn't know how to verify that hypothesis.
It's also weird that my solution works, given that select already uses a user-chosen timeout, such that I would think it internally sleeps anyway. Apparently not on Android.
What is the proper way to close a connection to a UsbAccessory in Android?
It seems the even in the stock Google example, if I connect and accessory, exit the app and then go back to it, the connection is not re-established.
Looking closely, it seems that after calling close() on the FileDescriptor, it won't open again, and a "could not open /dev/usb_accessory" log is emitted.
NOT calling close() is a bad option, as a thread blocking on read() will not be released. Upon physical disconnection / reconnection of the device everything is OK.
It seems really surprising that the simple use-case of exiting the app and then opening it again does not work in the reference application and even more surprising if it is not feasible.
I'm using a Nexus S running stock Android 2.3.6.
The problem is that the reading thread never exits, thus the file descriptor stays open, and cannot be opened again when the app is resumed.
This has been confirmed to be a bug:
http://code.google.com/p/android/issues/detail?id=20545
Vote on this bug if you care about it.
try to reconnect twice
it seams that the first time that is unsuccess will close the connection and then try again to open it will work!
for me it worked!
My app displays data from a steady stream of Bluetooth text input.
In Android 2.3.4, if I close the socket the read immediately throws an IO exception. In 2.2 is does only most of the time.
I am trying to stop the reading when onStop() is called. Then in onStart() I reconnect.
Is there a better way to kill the thread that is suspended on an inputStream read that is likely to work over all versions?
Thanks
TomZ
I tried interrupting the task and got bogged down in multiple types of exceptions depending on what it was doing at the time of the interrupt and getting compile errors that I was catching exceptions that it said could not be thrown. Even when I did get some working code, it still had reliability problems on Froyo (Galaxy S - Vibrant).
So I backed up and tried using InputStream.available in a loop with a short sleep and a check of a flag that is set to end the read task (so the task was never suspended except on the sleep). This worked great on various android versions.
It seems the trick is to not externally stop the thread but to let it detect the need to quit and return on it's own.
Seems a bit of a kludge, sort of polling the reads. But the code is now stable and the phone performance does not seem to suffer.
I've released my second game project on the Android Market this week, and immediately had multiple 1-star reports due to force closes. I tested it on many handsets and many emulators with zero issues. I'm completely at a loss for how to proceed and looking for advice.
I use Thread.setDefaultUncaughtExceptionHandler to intercept and report uncaught exceptions, then close gracefully. The people reporting force closes aren't getting to any of that, even though it is the first thing set in the application's main task constructor, and everything is wrapped in try/catches throughout. They are also reporting that there is no "Send Report" option in the force close popup (providing the Developer Console error reports), so I have absolutely no way of knowing what the problem is.
Uses Android 2.0, with android:minSdkVersion="5". Only Permission required is INTERNET.
(on Android market as 'Fortunes of War FREE' if you want to test)
I'm a bit surprised about the missing "Send report" button. What API level did you build the game with? I usually build the level with your minimum API level to make sure you're not using any API calls beyond that, but then switch back to the highest API level so you can use functionality like "install to SD".
I'm sure there's at least one user who wrote you a mail. Can you ask them to install LogCollector and mail you the log?
Btw, in general, I wouldn't use Thread.setDefaultUncaughtExceptionHandler so there IS the option to send a report. (It's ominously missing in your case, but normally, it should be there.)
Btw btw, the exception handler applies to the current thread. If you have an OpenGL app, maybe the crash happens in the GL thread?
I'm not sure if I understood you correctly, but as far as I know Android only shows that report dialog if you use its default UncaughtExceptionHandler.
Try this:
In your UncaughtExceptionHander's constructor, call Thread.getDefaultUncaughtExceptionHandler and save the returned object in a variable (let's call it defaultHandler). In your Handler's uncaughtException() do the things you want to do, and then call defaultHandler.uncaughtException() afterwards.
Maybe something you should know:
In my experience, your Context isn't functional anymore at uncaughtException(). So, you can't send broadcasts, etc anymore.
By the way, if you really wrapped everything in try/catch, that could be the reason why error reporting doesn't work as expected? :P
Good luck
Tom
Perhaps the force closes are caused by stalls, rather than exceptions. Users may not notice the difference. This kind of problem can occur more often if users have CPU hogging services running at the same time as your application, which explains why you're not seeing the issue in your testing.
Permission Internet sounds a lot like you try to transfer data from the net, which is very fast in your local LAN, but all of a sudden becomes slow (and time consuming) when people try this over their GSM connections.
If you then do the data transfer in the UI thread, this one is blocked and the system detects the block - but then this should end up in a "Did not respond" -- but then I've seen one user report an error with in the market on my app that was such a slow down cause.