09-24-2013 07:24 AM
I have an app, that is not aggresively multithreaded, but does spin off a few tasks into separate threads, principally for the purpose of maintaining UI responsiveness during processor-intensive tasks.
I have noticed in BlackBerry, that threading does not feel as it does on Android. My UI sometimes freezes and it takes quite a while to unfreeze it. Sometimes the threads just seem to die silently (or get stuck, for that matter).
Are there any recommendations from on the usage of threads in Android Runtime? We are willing to put some effort into having our app run smoothly on BlackBerry, but we hafve not found any documentation regarding threads in Android Runtime on BlackBerry. Could perhaps BlackBerry developers write up some recommendations regarding threads?
It would help us a great deal, if we knew of limitations regarding threads.
09-26-2013 04:04 PM
Thanks for stopping by the blog rruzic,
Could you elaborate on your testing efforts? Have you noticed this to be the case on the 10.2 operating system as well as prior iterations? With the inclusion of hardware acceleration in 10.2, alongside the Jelly Bean runtime update, the responsiveness of UI threads is much improved while allowing the CPU to focus on operational processes instead of those geared towards the UI.
09-27-2013 04:41 AM
Thank you for your answer, jdreher.
We have an android app and we are porting it to BleckBerry. We have noticed a general UI responsivness to be somewhat clunky and lagging, but the specific problem I was talking about, was a slider UI widget, which spins off a thread on each user action. The thread is rather expensive, it does some image manipulation. We have noticed, that when the user touches the slider a few times (three or four times) in a short time period, the UI would lock-up. Even when the threads all finished, the slider widget would remain locked. Our app does not lock the UI programatically, the widget has to get locked by the system in some way. We have not experienced this on Android, and we tested with a lot of low-end devices, as well as many devices running legacy Android 2.1 and 2.3.
The testing was done on a Blackberry Q10 device running Blackberry 10.1. No upgrades have been done on the device.
So you are saying that we should upgrade our test devices to 10.2 and release our app for 10.2 and newer?
10-17-2013 10:04 AM
bbenniger: Actually no, the worker thread has a handle to the UI thread and delivers processed data via the Android's runOnUiThread() call. No spin on wait.
In general threads in BlackBerry Android runtime seem to be a lot less "threaded" then threads on regular Android. I have a bunch of things in my app, that were supposed to run concurrently, but instead they run sequentially in random order, as if I had procedural code. Is there a way to tweak things in Android Runtime, so that threads would be more thread-like?
10-17-2013 10:16 AM
Android threads are pthreads at the OS level. I will say this though, thread scheduling is completely different in Linux vs QNX, but most of that should be hidden from you. The only time it will matter is if you start changing thread priority in your app (which the Google docs doesn't recommend unless you're decreasing priority, i.e. marking threads as background). Are you perhaps increasing thread priorities?
10-17-2013 10:24 AM
I do also recommend you try it out on 10.2. Without getting into specifics I can think of a few changes that have gone in that may (or may not) effect what you're seeing.
10-18-2013 03:34 AM
Thank you for your suggestions. No, I'm not changing thread priorities, but Android itseld distinguishes between the UI thread and other threads. I'm not quite sure how it's done behind the scenes, but I do know that the UI thread has something of a special status.
In my code i'm doing something like this (i'll try to write ti as clear as possible):
1. User clicks a button
2. On UI thread show a progress wheel
3. Start a worker thread
4. On worker thread finish, hide the progress wheel
5. Display the result
What should happen (and does happen, when running on Android proper) is, the user clicks a button, progress wheel is shown, then progress wheel disappears and the result of the worker is displayed.
On BlackBerry, however, when user clicks the button, nothing happens, the entire UI becomes unresponsive, then after a while the progress wheel flashes for a split second and the result is displayed. Sometimes the progress wheel is displayed for a bit longer, but it is not spinning, it is stationary.
Considering the fact, that the same code runs as expected on Android proper, I can not suspect anything other than that there is something significantly different with threads on BlackBerry Android runtime.
10-23-2013 09:00 AM
I believe I need to report my latest findings.
My app upon start was running ~20 threads, 13 of which were opened by the WebKit object in google's AdMob AD library. Webkit runs a main thread, 4 specific task threads (cookies and the like) and 10 loader threads. Removing the ads slashed the number of threads down to 9(Main thread, 5 AsyncTask threads, 3 Binder threads).
Removing AdMob had a remarkable impact on UI. We had a lot of problems with UI responsiveness, it seemed as if touchscreen events were getting lost somewhere, but we could not figure out where. It turned out, they were indeed getting lost, some layer somewhere dropped them. We had a slider widget, which was horrifically unresponsive, it responded to perhaps 50% of user input, but upon removing AdMob it became not only 100% responsive, but also snappy and lag-free.
Concurrency has somewhat improved, but it is still far from satisfactory. Now when I run some procedure in an AsyncTask, while displaying a progress dialog on the UI, the progress dialog is about 50% more responsive, then it was with WebKit running, but this still means, that even though the code says, the progress wheel should pop up before the start of the AsyncTask, it is going to start a few seconds after the start of AsyncTask, and it is still clunky and freezing all the time, instead of the smooth spinning that we get on Android proper.
I don't think I can get my thread count any lower then what I have, Dalvik starts the 2 Binder threads and the 5 AsyncTask threads on app start. I will eliminate all the inline ad-hoc runnables I have in the code and turn them into AsyncTasks, so that threads from the Asyncask pool will be run, instead of new threads. I will report back, if I get any significant improvements.