Is there a way of finding out where my app threw an ANR (Application Not Responding). I took a look at the traces.txt file in /data and I see a trace for my application. This is what I see in the trace.
DALVIK THREADS:
"main" prio=5 tid=3 TIMED_WAIT
| group="main" sCount=1 dsCount=0 s=0 obj=0x400143a8
| sysTid=691 nice=0 sched=0/0 handle=-1091117924
at java.lang.Object.wait(Native Method)
- waiting on <0x1cd570> (a android.os.MessageQueue)
at java.lang.Object.wait(Object.java:195)
at android.os.MessageQueue.next(MessageQueue.java:144)
at android.os.Looper.loop(Looper.java:110)
at android.app.ActivityThread.main(ActivityThread.java:3742)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:497)
at dalvik.system.NativeStart.main(Native Method)
"Binder Thread #3" prio=5 tid=15 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x434e7758
| sysTid=734 nice=0 sched=0/0 handle=1733632
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #2" prio=5 tid=13 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x433af808
| sysTid=696 nice=0 sched=0/0 handle=1369840
at dalvik.system.NativeStart.run(Native Method)
"Binder Thread #1" prio=5 tid=11 NATIVE
| group="main" sCount=1 dsCount=0 s=0 obj=0x433aca10
| sysTid=695 nice=0 sched=0/0 handle=1367448
at dalvik.system.NativeStart.run(Native Method)
"JDWP" daemon prio=5 tid=9 VMWAIT
| group="system" sCount=1 dsCount=0 s=0 obj=0x433ac2a0
| sysTid=694 nice=0 sched=0/0 handle=1367136
at dalvik.system.NativeStart.run(Native Method)
"Signal Catcher" daemon prio=5 tid=7 RUNNABLE
| group="system" sCount=0 dsCount=0 s=0 obj=0x433ac1e8
| sysTid=693 nice=0 sched=0/0 handle=1366712
at dalvik.system.NativeStart.run(Native Method)
"HeapWorker" daemon prio=5 tid=5 VMWAIT
| group="system" sCount=1 dsCount=0 s=0 obj=0x4253ef88
| sysTid=692 nice=0 sched=0/0 handle=1366472
at dalvik.system.NativeStart.run(Native Method)
----- end 691 -----
How can I find out where the problem is? The methods in the trace are all SDK methods.
An ANR happens when some long operation takes place in the "main" thread. This is the event loop thread, and if it is busy, Android cannot process any further GUI events in the application, and thus throws up an ANR dialog.
Now, in the trace you posted, the main thread seems to be doing fine, there is no problem. It is idling in the MessageQueue, waiting for another message to come in. In your case the ANR was likely a longer operation, rather than something that blocked the thread permanently, so the event thread recovered after the operation finished, and your trace went through after the ANR.
Detecting where ANRs happen is easy if it is a permanent block (deadlock acquiring some locks for instance), but harder if it's just a temporary delay. First, go over your code and look for vunerable spots and long running operations. Examples may include using sockets, locks, thread sleeps, and other blocking operations from within the event thread. You should make sure these all happen in separate threads. If nothing seems the problem, use DDMS and enable the thread view. This shows all the threads in your application similar to the trace you have. Reproduce the ANR, and refresh the main thread at the same time. That should show you precisely whats going on at the time of the ANR
You can enable StrictMode in API level 9 and above.
StrictMode is most commonly used to catch accidental disk or network
access on the application's main thread, where UI operations are
received and animations take place. By keeping your application's main thread
responsive, you also prevent ANR dialogs from being shown to users.
public void onCreate() {
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectAll()
.penaltyLog()
.penaltyDeath()
.build());
super.onCreate();
}
using penaltyLog() you can watch the output of adb logcat while you
use your application to see the violations as they happen.
You are wondering which task hold a UI Thread. Trace file gives you a hint to find the task. you need investigate a state of each thread
State of thread
running - executing application code
sleeping - called Thread.sleep()
monitor - waiting to acquire a monitor lock
wait - in Object.wait()
native - executing native code
vmwait - waiting on a VM resource
zombie - thread is in the process of dying
init - thread is initializing (you shouldn't see this)
starting - thread is about to start (you shouldn't see this either)
Focus on SUSPENDED, MONITOR state. Monitor state indicates which thread is investigated and SUSPENDED state of the thread is probably main reason for deadlock.
Basic investigate steps
Find "waiting to lock"
you can find monitor state "Binder Thread #15" prio=5 tid=75 MONITOR
you are lucky if find "waiting to lock"
example : waiting to lock <0xblahblah> (a com.foo.A) held by threadid=74
You can notice that "tid=74" hold a task now. So go to tid=74
tid=74 maybe SUSPENDED state! find main reason!
trace does not always contain "waiting to lock". in this case it is hard to find main reason.
I've been learning android for the last few months, so I'm far from an expert, but I've been really disappointed with the documentation on ANRs.
Most of the advice seems to be geared towards avoiding them or fixing them by blindly looking through your code, which is great, but I couldn't find anything on analyzing the trace.
There are three things you really need to look for with ANR logs.
1) Deadlocks: When a thread is in the WAIT state, you can look through the details to find who it's "heldby=". Most of the time, it'll be held by itself, but if it's held by another thread, that's likely to be a danger sign. Go look at that thread and see what it's held by. You might find a loop, which is a clear sign that something has gone wrong. This is pretty rare, but it's the first point because when it happens, it's a nightmare
2) Main thread Waiting: If your main thread is in the WAIT state, check if it's held by another thread. This shouldn't happen, because your UI thread shouldn't be held by a background thread.
Both of these scenarios, mean you need to rework your code significantly.
3) Heavy operations on the main thread: This is the most common cause of ANRs, but sometimes one of the harder to find and fix. Look at the main thread details. Scroll down the stack trace and until you see classes you recognize (from your app). Look at the methods in the trace and figure out if you're making network calls, db calls, etc. in these places.
Finally, and I apologize for shamelessly plugging my own code, you can use the python log analyzer I wrote at https://github.com/HarshEvilGeek/Android-Log-Analyzer This will go through your log files, open ANR files, find deadlocks, find waiting main threads, find uncaught exceptions in your agent logs and print it all out on the screen in a relatively easy to read manner. Read the ReadMe file (which I'm about to add) to learn how to use it. It's helped me a ton in the last week!
You need to look for "waiting to lock" in /data/anr/traces.txt file
for more details: Engineer for High Performance with Tools from Android & Play (Google I/O '17)
Whenever you're analyzing timing issues, debugging often does not help, as freezing the app at a breakpoint will make the problem go away.
Your best bet is to insert lots of logging calls (Log.XXX()) into the app's different threads and callbacks and see where the delay is at. If you need a stacktrace, create a new Exception (just instantiate one) and log it.
What Triggers ANR?
Generally, the system displays an ANR if an application cannot respond to user input.
In any situation in which your app performs a potentially lengthy operation, you should not perform the work on the UI thread, but instead create a worker thread and do most of the work there. This keeps the UI thread (which drives the user interface event loop) running and prevents the system from concluding that your code has frozen.
How to Avoid ANRs
Android applications normally run entirely on a single thread by default the "UI thread" or "main thread"). This means anything your application is doing in the UI thread that takes a long time to complete can trigger the ANR dialog because your application is not giving itself a chance to handle the input event or intent broadcasts.
Therefore, any method that runs in the UI thread should do as little work as possible on that thread. In particular, activities should do as little as possible to set up in key life-cycle methods such as onCreate() and onResume(). Potentially long running operations such as network or database operations, or computationally expensive calculations such as resizing bitmaps should be done in a worker thread (or in the case of databases operations, via an asynchronous request).
Code: Worker thread with the AsyncTask class
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
// Do the long-running work in here
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
// This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
// This is called when doInBackground() is finished
protected void onPostExecute(Long result) {
showNotification("Downloaded " + result + " bytes");
}
}
Code: Execute Worker thread
To execute this worker thread, simply create an instance and call execute():
new DownloadFilesTask().execute(url1, url2, url3);
Source
http://developer.android.com/training/articles/perf-anr.html
Basic on #Horyun Lee answer, I wrote a small python script to help to investigate ANR from traces.txt.
The ANRs will output as graphics by graphviz if you have installed grapvhviz on your system.
$ ./anr.py --format png ./traces.txt
A png will output like below if there are ANRs detected in file traces.txt. It's more intuitive.
The sample traces.txt file used above was get from here.
Consider using the ANR-Watchdog library to accurately track and capture ANR stack traces in a high level of detail. You can then send them to your crash reporting library. I recommend using setReportMainThreadOnly() in this scenario. You can either make the app throw a non-fatal exception of the freeze point, or make the app force quit when the ANR happens.
Note that the standard ANR reports sent to your Google Play Developer console are often not accurate enough to pinpoint the exact problem. That's why a third-party library is needed.
not sure if this will help. My issue was the app crashes and freezes my devices then forced it to restart on devices with android 10 but runs fine with the android 6 nothing showed in the logcat. The crashes wasn't easy to reproduce and very unpredictable.
I spent almost 2 wks searching and troubleshooting with ANR but no avail.
Finally syncing the gradle fixed all issues..... rookie mistake.
Hope this would help someone.
my issue with ANR , after much work i found out that a thread was calling a resource that did not exist in the layout, instead of returning an exception , i got ANR ...
For published apps, Google play console itself shows Exact ANRs report like crash report. It will show you all the information which class or Thread is causing ANR, Occurances and all other details.
Your App Dashboard-> Explore Android Vitals Tab -> View Core Vitals Detail (ANR section)-> Select your apk or artifect vesrion -> Crashes and ANR page just select ANRs from drop down. It will list all the ANRs.
You can navigate to specific ANR and check details.
After searching for many solutions for solving ANR crashes on Android, I stumbled onto this link:
https://developer.android.com/studio/debug/bug-report
Connect your android device to a computer with ADB installed
Open terminal
Run the following command (replace "path" with where you want your zip folder saved e.g. ~/folder/report):
adb bugreport
This enabled me to access all ANR (anr* files) bug reports that gave me a full tracebacks under the folder:
FS -> data -> anr -> anr* files
Related
I am debugging an Android Project and notice that there are asterisks on some of the Thread ID. What is it for?
Daemon threads are shown with an asterisk (*). This will be one of the following:
running - executing application code
sleeping - called Thread.sleep()
monitor - waiting to acquire a monitor lock
wait - in
Object.wait()
native - executing native code
vmwait - waiting on a
VM resource
zombie - thread is in the process of dying
init - thread
is initializing (you shouldn't see this)
you can read more about here
In my own testing I did not encounter this issue but once my app was published the ANRs started flooding in. My app currently has 22 ANRs with some being reported as many 100 times. All of the traces seem to be from attempting to create a new Realm instance on the UI thread.
"main" prio=5 tid=1 MONITOR
| group="main" sCount=1 dsCount=0 obj=0x4183ede0 self=0x417548b8
| sysTid=19680 nice=0 sched=0/0 cgrp=apps handle=1073975684
| state=S schedstat=( 2816413167 710323137 3658 ) utm=215 stm=66 core=1
at io.realm.Realm.createAndValidate(Realm.java:~495)
- waiting to lock <0x41df9c98> held by tid=12 (IntentService[UASyncService])
at io.realm.Realm.create(Realm.java:486)
at io.realm.Realm.getInstance(Realm.java:404)
at io.realm.Realm.getInstance(Realm.java:366)
at io.realm.Realm.getInstance(Realm.java:347)
I believe the root of this issue is, as beeender mentioned, that I have an open Realm transaction in a worker thread which is blocking my attempts to get a Realm instance on the UI thread causing ANRs.
I will update again later after I have a solution.
*Edit: Added updated information.
Realm no longer has this issue.
For reference my solution at the time was:
Thanks to beeender for pointing me in the right direction and linking this PR https://github.com/realm/realm-java/pull/1297
Issue
When there is a pending Realm transaction, any call to Realm.getInstance on a different thread will block until the pending transaction has been committed or cancelled.
In my case I have an IntentService which populates my Realm with existing user data, meanwhile I try to display any current data by querying Realm on the UI thread. Although the queries are simple and don't cause any issues normally, if there is a pending transaction in the IntentService, calling Realm.getInstance will be blocked, blocking the UI thread, potentially causing an ANR.
My first attempt at a solution was to pull beeender's PR branch and create a jar. I believe this fix did get me one step further, allowing the Realm instance to be created without blocking, but the UI thread was still blocked by small transactions I was trying to perform on UI thread.
Solution
The solution I implemented involves several steps:
Create duplicate objects for all of my models. The duplicates do not extend RealmObject (since RealmObjects cannot be used across threads.)
Move all accesses to Realm onto background threads. Basically I wrapped my queries in AsyncTasks and added listeners which return the non-RealmObject version of the model.
Make more small transactions rather than fewer large transactions. Where previously I began and committed transactions on either side of a loop which created many new RealmObjects, I now begin and commit the transaction per object. The purpose of this is to reduce the total uninterrupted time that Realm may be in an open transaction state so my queries providing data for the UI can complete without having to wait as long.
Conclusion
I was initially hesitant to use Realm due to it still being in beta as well as the caveat that RealmObjects cannot be used across threads. After some tests I felt confident that I could perform simple queries on the UI thread without issue (still with a guilty feeling in my gut though.)
Overall Realm is a great project to keep an eye on but I feel that it is not ready for large scale commercial projects. Using Realm on this project may have saved some time upfront but it cost many displeased customers and a difficult to diagnose issue.
*Edit: Clarified issue.
Realm's introduction example shows them using an AsyncTask to do their reads and writes.
Any costly I/O, be it from the network, a database, or a large file should typically be kept off the main thread as it will cause a sluggish UI. Without seeing your code, I'd guess that if you're getting an ANR you're probably doing something too complex for the main thread.
The application I am working on, works correctly when the screen is on, and for any length of time, but as soon as the phone goes to sleep and 10 seconds have elapsed, I get an error in my logcat,
I/art Thread[5,tid=318,WaitingInMainSignalCatcherLoop,Thread*=0xaf60e400,peer=0x12c00080,"Signal Catcher"]: reacting to signal 3
I pulled the traces file and tried to understand what was causing this issue and read through androids page on application performance, I have figured out that, it is being caused because a BroadcastReceiver hasn't executed in 10 seconds,
A BroadcastReceiver hasn't finished executing within 10 seconds.
From reading the traces file, I believe it has something to do with the timeout of the screen being broadcast and the action not being completed.
"ActivityManager" prio=5 tid=16 TimedWaiting
| group="main" sCount=1 dsCount=0 obj=0x12d41970 self=0xac884400
| sysTid=859 nice=-2 cgrp=apps sched=0/0 handle=0xb50e9e80
| state=S schedstat=( 443987410679 259509083288 699634 ) utm=18416 stm=25982 core=2 HZ=100
| stack=0xa14fa000-0xa14fc000 stackSize=1036KB
| held mutexes=
at java.lang.Object.wait!(Native method)
- waiting on <0x03423764> (a com.android.server.am.ActivityManagerService$6)
at java.lang.Object.wait(Object.java:422)
at com.android.server.am.ActivityManagerService.dumpStackTraces(ActivityManagerService.java:4969)
- locked <0x03423764> (a com.android.server.am.ActivityManagerService$6)
at com.android.server.am.ActivityManagerService.dumpStackTraces(ActivityManagerService.java:4946)
at com.android.server.am.ActivityManagerService.appNotResponding(ActivityManagerService.java:5187)
at com.android.server.am.BroadcastQueue$AppNotResponding.run(BroadcastQueue.java:171)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.os.HandlerThread.run(HandlerThread.java:61)
at com.android.server.ServiceThread.run(ServiceThread.java:46)
Can someone please point me in the right direction to resolve this issue?
How can I find the root cause of the issue.
What I had tried (in my ignorance) I tried removing all the Broadcast Receivers in the code, that didn't help., obviously.
I got rid of the wakeLocks in an attempt to resolve the issue, but that also didn't help.
Any help is greatly appreciated.
I'm having the same problem here with an operation that should not take so much time, but for some reason, it is.
From the official Android Documentation:
The specific constraint on BroadcastReceiver execution time emphasizes what broadcast receivers are meant to do: small, discrete amounts of work in the background such as saving a setting or registering a Notification. So as with other methods called in the UI thread, applications should avoid potentially long-running operations or calculations in a broadcast receiver. But instead of doing intensive tasks via worker threads, your application should start an IntentService if a potentially long running action needs to be taken in response to an intent broadcast.
http://developer.android.com/training/articles/perf-anr.html
I've a strange black screen problem at app restart after the app wasn't used for a while reported by users in the play store developer console with an ANR with a quite strange stack trace:
----- pid 2704 at 2013-08-15 09:08:32 -----
Cmd line: system_server
DALVIK THREADS:
(mutexes: tll=0 tsl=0 tscl=0 ghl=0 hwl=0 hwll=0)
"main" prio=5 tid=1 NATIVE
| group="main" sCount=1 dsCount=0 obj=0x400281b8 self=0xd088
| sysTid=2704 nice=0 sched=0/0 cgrp=default handle=-1345006464
| schedstat=( 29713532638 35237133707 131286 )
at com.android.server.SystemServer.init1(Native Method)
at com.android.server.SystemServer.main(SystemServer.java:918)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(...)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
...
and no thread with app code involved. I can kind of reproduce it on one of my test devices but it is quite random and takes really long to run into the error. But if I'm able to I get the following messages in the log of the device right after starting the app:
I/ActivityManager( 2704): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.example.client.android/.ExampleMainActivity bnds=[125,494][235,632] } from pid 2908
W/ActivityManager( 2704): Receiver during timeout: BroadcastFilter{40b8b180 ReceiverList{40b8b108 32495 com.example.client.android/10107 remote:40b34b28}}
I/ActivityManager( 2704): Skipping duplicate ANR: ProcessRecord{40bfc8c0 32495:com.example.client.android/10107} Broadcast of Intent { act=android.intent.action.SCREEN_OFF flg=0x40000000 }
W/ActivityManager( 2704): Activity idle timeout for HistoryRecord{40578b78 com.example.client.android/.ExampleMainActivity}
I already googled around and found the following posts on StackOverflow concerning these messages:
Activity idle timeout for HistoryRecord?
Activity idle timeout for HistoryRecord
And the following post in google groups:
https://groups.google.com/forum/?fromgroups#!topic/android-developers/TfkPlN5b-ig
I checked for services, if there's anything heavy-weight in onReceive of the BroadcastReceivers but haven't found anything.
We use a OnGlobalChangeLayoutListener, which applied an View.invalidate() to work around a WebView repaint probelm which maybe could cause a draw-Looping. I removed it but still do get the problem.
Anyone maybe having the same problem and having an idea how to fix it or to isolate it? I'm pretty much out of ideas here and would love to understand what's going on here.
UPDATE
I forgot to mention: if this black screen problem happened the only way getting the app out of this is a forced stop of the application process. Otherwise the log lines get logged every time I try to start the app.
UPDATE 2
A more detailed description of what is happening as requested: The black screen occurs very randomly. It always happens at start of the app and if happened only a force stop gets the app out of this. It seems to happen only after the app wasn't used for a longer and was probably swapped out of memory. And it looks like only Android 2.x devices are affected although I'm not sure with this.
UPDATE 3
I've added a button which calls android.os.Process.killProcess(Process.myPid()); and if I call this again and again I've been able to reproduce it after some time, by starting the app and quitting it using the button. After some time (quite random), I get this right after quitting using the button:
E/JavaBinder( 2704): !!! FAILED BINDER TRANSACTION !!!
followed by a:
W/ActivityManager( 2704): Activity pause timeout for HistoryRecord{40976dd8 com.example.client.android/.ExampleMainActivity}
and next time I restart the app I just get a black screen and the log messages mentioned above. I've been unable to reproduce the same with an android 4.1 device, only with two 2.3 devices.
Googling around I found this:
http://androiddiscuss.com/1-android-discuss/42614.html
suggesting the binder transaction buffer is somewhat exhausted. We use the MediaPlayer, InApp-Billing and Google Cloud Messages which use binding. I removed all of them and still get into this error. Maybe someone knows other hidden binder related stuff to check for?
I was finally able to identify the faulty component: I recently updated the used Admob-SDK from 6.2.1 to 6.4.1 and the black screen (and the Java-Binder message) happens since the update. Rolling back to 6.2.1 solved the issue.
What are all the possible thread states during execution for native (C/C++) threads on an Android device? Are they the same as the Java Thread States? Are they Linux threads? POSIX threads?
Not required, but bonus points for providing examples of what can cause a thread to enter each state.
Edit: As requested, here's the motivation:
I'm designing the interface for a sampling profiler that works with native C/C++ code on Android. The profiler reports will show thread states over time. I need to know what all the states are in order to a) know how many distinct states I will need to possibly visually differentiate, and b) design a color scheme that visually differentiates and groups the desirable states versus the undesirable states.
I've been told that native threads on Android are just lightweight processes. This agrees with what I've found for Linux in general. Quoting this wiki page:
A process (which includes a thread) on a Linux machine can be in any of the following states:
TASK_RUNNING - The process is either executing on a CPU or waiting to be executed.
TASK_INTERRUPTIBLE - The process is suspended (sleeping) until some condition becomes true. Raising a hardware interrupt, releasing a system resource the process is waiting for, or delivering a signal are examples of conditions that might wake up the process (put its state back to TASK_RUNNING). Typically blocking IO calls (disk/network) will result in the task being marked as TASK_INTERRUPTIBLE. As soon as the data it is waiting on is ready to be read an interrupt is raised by the device and the interrupt handler changes the state of the task to TASK_INTERRUPTIBLE. Also processes in idle mode (ie not performing any task) should be in this state.
TASK_UNINTERRUPTIBLE - Like TASK_INTERRUPTIBLE, except that delivering a signal to the sleeping process leaves its state unchanged. This process state is seldom used. It is valuable, however, under certain specific conditions in which a process must wait until a given event occurs without being interrupted. Ideally not too many tasks will be in this state.
For instance, this state may be used when a process opens a device file and the corresponding device driver starts probing for a corresponding hardware device. The device driver must not be interrupted until the probing is complete, or the hardware device could be left in an unpredictable state.
Atomic write operations may require a task to be marked as UNINTERRUPTIBLE
NFS access sometimes results in access processes being marked as UNINTERRUPTIBLE
reads/writes from/to disk can be marked thus for a fraction of a second
I/O following a page fault marks a process UNINTERRUPTIBLE
I/O to the same disk that is being accessed for page faults can result in a process marked as UNINTERRUPTIBLE
Programmers may mark a task as UNINTERRUPTIBLE instead of using INTERRUPTIBLE
TASK_STOPPED - Process execution has been stopped; the process enters this state after receiving a SIGSTOP, SIGTSTP, SIGTTIN, or SIGTTOU signal.
TASK_TRACED - Process execution has been stopped by a debugger.
EXIT_ZOMBIE - Process execution is terminated, but the parent process has not yet issued a wait4() or waitpid() system call. The OS will not clear zombie processes until the parent issues a wait()-like call.
EXIT_DEAD - The final state: the process is being removed by the system because the parent process has just issued a wait4() or waitpid() system call for it. Changing its state from EXIT_ZOMBIE to EXIT_DEAD avoids race conditions due to other threads of execution that execute wait()-like calls on the same process.
Edit: And yet the Dalvik VM Debug Monitor provides different states. From its documentation:
"thread state" must be one of:
1 - running (now executing or ready to do so)
2 - sleeping (in Thread.sleep())
3 - monitor (blocked on a monitor lock)
4 - waiting (in Object.wait())
5 - initializing
6 - starting
7 - native (executing native code)
8 - vmwait (waiting on a VM resource)
"suspended" [a separate flag in the data structure] will be 0 if the thread is running, 1 if not.
If you design a system app that has to work with threads in even more advanced way than usual app, I'd first start by examining what API is available on Android to access threads.
The answer is pthread = POSIX threads, with pthread.h header file, implemented in Bionic C library. So you have starting point for knowing what you can achieve.
Another thing is that Android doesn't implement full pthread interface, only subset needed for Android to run.
More on threads + Bionic here, and how they interact with Java and VM is described here. Also I feel that thread is actually a process, as my code uses setpriority(PRIO_PROCESS, gettid(), pr); to set new thread's priority - I don't recall where I got this info, but this works.
I assume that thread may be in running, finished or blocked (e.g. waiting for mutex) state, but that's my a bit limited knowledge since I never needed other thread state.
Now question is if your app can actually retrieve these states using available API in NDK, and if there're more states, if your users would be really interested to know.
Anyway, you may start by displaying possibly incomplete states of threads, and if your users really care, you'd learn about another states from users' feedback and requests.
Google:
Thread.State BLOCKED The thread is blocked and waiting for a lock.
Thread.State NEW The thread has been created, but has never been started.
Thread.State RUNNABLE The thread may be run.
Thread.State TERMINATED The thread has been terminated.
Thread.State TIMED_WAITING The thread is waiting for a specified amount of time.
Thread.State WAITING The thread is waiting.
These states are not very well explained - I don't see the difference between BLOCKED and WAITING, for example.
Interestingly, there is no 'RUNNING' state - do these devices ever do anything?