How to stop a thread that is suspended on a Bluetooth read - android

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.

Related

c++11 multithreading issues with Android where some threads are not scheduled properly

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.

How can an App freeze Android OS

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
}

Is there an Android InputStream class that times out?

I am currently using an InputStream in my application (import java.io.InputStream) and have run into an issue regarding timing out. The way the InputStream seems to work is that it waits for a certain amount of bits and then proceeds. For my application this works a lot of the time, but there are cases where I am expecting the read to fail due to timeout. Does anyone know a way to do this?
I have found many examples of creating threads to run alongside the read() function and cancel it, but I was wondering if there is an existing class which lets me use an InputStream that times out.
This largely depends on where you are reading from. If it is from a file (or local) socket, there is no timeout. If it is from a remote socket, you can specify timeout when creating the socket. If it times out you should get an exception. Using threads/AsyncTask is the way to go, but you generally cannot interrupt a blocked read, unless you are using Java NIO.
And no, it is not ridiculous, how do you propose for it to 'time out on its own'? Someone has to signal the timeout, and that someone is either some sort of monitor thread or the OS raising an error.
I would use AsyncTask<> for this. You can try to start reading the stream asynchronously and then at a time of your choosing cancel the task, rather than blocking your UI. Documentation here

Android Force Close Uncatchable Unreportable

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.

Android app ANR when wi-fi connectivity is lost

I'm in the middle of debugging an issue where ANR message gets displayed when wi-fi connectivity is lost. So when the application starts it has WI-Fi connectivity. The connectivity drops and during the switching from wi-fi to 3G.. no data can be fetched from the sever. In my code i catch the exception and then after a brief sleep period i try again. But the application displays ANR message and crashes. My question is where should i even begin with. what's the lead . I looked in the LOGCAT.. but it has no indication which states the application is hanging at a particular place. Any inputs from expert on this.
BTW my devise is Moto Droid Adroid 2.2
Off the top of my head two things could be the problem:
1) You could be getting an ANR because you are doing blocking IO in the UI thread. This is a bad thing as you have discovered. Your solution is to do all blocking IO in separate background threads. Even if this is not directly the case it is still best practice to do IO on a thread separate from the UI thread.
2) The socket is bound to the wifi interface. When that interface is disabled (i.e., connection is lost) that socket is useless. If you are catching exceptions and then just naively attempting to preform another operation on that socket it's going to throw another exception. This will send your application into an infinite loop of exception catching. You should check the exceptions and throw away the socket appropriately when the network interface is lost.

Categories

Resources