What is the impact of setting different priority on handler thread? - android

I'm have a handler thread with thread priority set to background,
myHandlerThread = new HandlerThread(HANDLER_THREAD_NAME,
Process.THREAD_PRIORITY_BACKGROUND);
On this myHandlerThread I'm doing some operation to alter system property by invoking
SystemProperties.set(property, propertyValue);
I'm facing this exception frequently,
[Events]
java.lang.RuntimeException: failed to set system property
at android.os.SystemProperties.native_set(Native Method)
at android.os.SystemProperties.set(SystemProperties.java:130)
There can be multiple reasons which can cause this
1) The native code might have timed out when executing this code.
2) Since the thread is given with priority BACKGROUND it might not have time to execute when the CPU is busy and might have timed out at the end.
Will increasing the thread priority to NORMAL would help? Or how the thread will get timed out? Or what are the other reasons which could cause this issue?

myHandlerThread = new HandlerThread(HANDLER_THREAD_NAME,
Process.THREAD_PRIORITY_BACKGROUND);
Value of Process.THREAD_PRIORITY_BACKGROUND = 10
As you already know that in Java each thread has its own priority based on the thread which has created it. And we can change these priorities also like your above code.
By default, java provides priority scale between 0-10. But we can increase the scale by using Process.setThreadPriority() which provides scaling between (+/- 20).
Runnable r = ...
Thread thread = new Thread( new Runnable() {
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE);
r.run();
}
});
So currently your above code is equivalent to Thread.setPriority() which only sets the handler thread priority to 10 (least in scale(0-10)).
I think the first one could be the reason which you had mentioned above:
1) The native code might have timed out when executing this code.

Related

High frequency UI update - Android

I want to make 8 squares change colors between red/black periodically.
I acomplish this using timer.schedule with period time in milliseconds and it work
BUT then I realized that I need to use small time between this transitions (example nanoseconds).
To accomplish that I wrote this code:
timerTask = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run(){
//CODE OF THE TASK.
}
});
}
};
//To make schedule this task in 5 nanoseconds I use this!
exec = new ScheduledThreadPoolExecutor(1);
exec.scheduleAtFixedRate(timerTask, 0, 5, TimeUnit.NANOSECONDS);
But when I run this, the UI is not updating (seems to be stuck), but in logcat, all the logs are printing very fast. How can I achieve to make a task periodically x nanoseconds?
The entire Android UI runs at 60Hz- 60 updates per second. This means the minimum time between redraws is 16 ms. You cannot run it at a higher framerate. Nor are human eyes capable of seeing changes at a much higher frequency than that.
iOS and most video game consoles also work on a 60 Hz refresh rate. You'd find very few to no systems that go faster.
I'm not sure what exactly you're trying to accomplish, but I'm fairly certain you're trying to do it the wrong way.
ALSO: I notice your timer task posts to a handler. That means your timer task is going to tell the main thread to run something, and the timer task is running in nanoseconds. YOu're basically going to choke your main thread full of "run this task" messages, then eventually crash with an OOM error when the event queue becomes so massive it can't add any more (which may take several minutes), because there's no way you're processing them fast enough with the thread switching overhead.
After doing a lot of research, I realized that in order to get the view to refresh so quickly, I needed the use of SurfaceView and a Thread to make the UI redraw very fast, I really had no knowledge of this. Thanks for the help

RejectedExecutionException from AsyncTask, but haven't hit limits

My Android app has to deal with arriving messages which frequently come in bunches (especially during periods of flaky connectivity). I handle these incoming messages in AsyncTasks so that I don't interfere with the UI thread. If too many messages come in at once, I get a RejectedExecutionException. My error stack looks like this:
10-22 14:44:49.398: E/AndroidRuntime(17834): Caused by: java.util.concurrent.RejectedExecutionException: Task android.os.AsyncTask$3#414cbe68 rejected from java.util.concurrent.ThreadPoolExecutor#412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]
10-22 14:44:49.398: E/AndroidRuntime(17834): at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1967)
10-22 14:44:49.398: E/AndroidRuntime(17834): at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:782)
10-22 14:44:49.398: E/AndroidRuntime(17834): at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1303)
10-22 14:44:49.398: E/AndroidRuntime(17834): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:564)
I'm running the tasks with task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) so that incoming messages are processed in parallel.
What is confusing about this, and different from related StackOverflow questions that I can find (e.g. here and here), is that the number of active threads and queued tasks don't seem to be bumping up against the limits (which seem to be 128 and 10, respectively). See the stacktrace:
ThreadPoolExecutor#412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]
Why would I be getting this error message?
Why would I be getting this error message?
If the ThreadPoolExecutor is still running, you would get this error message only if you have exceeded the number of tasks that can be queued by the ThreadPoolExecutor. The only time the RejectedExecutionException is thrown is by the ThreadPoolExecutor.AbortPolicy which is the default RejectedExecutionHandler.
To quote from the javadocs:
If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
There is a maximum number of tasks. See this question/answer here: Is there a limit of AsyncTasks to be executed at the same time?
Here's a link for the sourcecode for AsyncTask.
private static final int CORE_POOL_SIZE = 5;
private static final int MAXIMUM_POOL_SIZE = 128;
private static final BlockingQueue<Runnable> sWorkQueue =
new LinkedBlockingQueue<Runnable>(10);
private static final ThreadPoolExecutor sExecutor =
new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory);
So it looks like it starts at 5 threads, has a queue of 10. Once the queue is full it can start up to 128 threads. So it looks like you have exceeded 138 simultaneous requests.
ThreadPoolExecutor#412716b8[Running, pool size = 128, active threads = 22, queued tasks = 0, completed tasks = 1323]
Trying to catch the ThreadPoolExecutor the exact moment that it runs out of space is going to be very hard and it will quickly turn into a heisenbug in that the more you look at the ThreadPoolExecutor numbers, the more you are going to affect the synchronization of that class and therefore you might make the bug go away.
In your case, by the time you get to log the exception with the details about the TPE, the condition must have passed.
This exception also occur if your Executor call shutdown method and after that you give new Task (Runnable) for execution.
Like
mThreadPoolExecutor.shutdown();
...
...
...
mThreadPoolExecutor.execute(new Runnable(){...});

Time an Android thread in a better way? (runs out of sync)

Hey I am currently designing an app where some code gets executed every 200ms. The thread I use for this looks like this (simplified):
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{ public void run()
{
handler.postDelayed(this, 200);
switch (status){
case 1: check(1);p2.setBackgroundColor(0x00000000); p1.setBackgroundColor(0xDDCC0000); status = 2; break;
case 2: check(2);p1.setBackgroundColor(0x00000000); p2.setBackgroundColor(0xAAAA0000); status = 1; break;
}
}
}; runnable.run();
check() contains some non-UI code lines.
The problem is, that the postDelayed-200-ms start, when the queue is fully executed and not at the beginning so all time that the system needs to execute the commands stacks and stacks all the time so these are actually ~210-230ms (depending on CPU load)
Then I tried to get the system date at the beginning of the thread and add 200ms to it but this results in some other, "heavier" errors.
I have no problem with more than 200ms delay, I just want to get it running stable.
I hope you understand my problem and can give some advice to me.
EDIT: I know got to know that the Handler runs acceptable (delay of 4ms on 200ms). The problem are the methods I am calling then. I will open a new question
If check() contains non-ui code lines then you should run those in a separate thread.
The bottom line is that the UI thread is *really busy, so, you can ask it to do something every 200ms but you aren't guaranteed any precision since the Device is doing its best to do all sorts of other things. When you say "heavier problems" what do you mean exactly?
I would try to start a Thread and just Log every 200ms to see if the device is willing to accurately do *anything at the rate you wish. If it does, then you can send messages to the UI thread to draw and if you find that its the drawing that is delayed, then perhaps you need to reduce your delay to give the UI thread time to finish drawing? (obviously this is also highly imprecise and will vary wildly from device to device).
Did you try doing it using Timers? A basic implementation would look like
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
}
}, 200, 200);
You can try using the alarm service as well. that should give you accurate (or at least consistent) results.

Run thread for less than a second

new Handler().postDelayed(new Runnable() {
public void run() {
//code
}
}, secondsDelayed * 1000);
here even if change value of 1000 to 100 or 10 thread runs for min 1sec.
This method postDelayed, has second parameter to let it know , in how much time it should start to run. not for how much time it should run, See Method info below
public final boolean postDelayed (Runnable r, long delayMillis)
Since: API Level 1
Causes the Runnable r to be added to the message queue, to be run after the
specified amount of time elapses. The runnable will be run on the thread to which this handler is attached.
Parameters
r The Runnable that will be executed.
delayMillis The delay (in milliseconds) until the Runnable will be executed.
Returns
Returns true if the Runnable was successfully placed in to the message queue. Returns false on failure, usually because the looper processing the message queue is exiting. Note that a result of true does not mean the Runnable will be processed -- if the looper is quit before the delivery time of the message occurs then the message will be dropped.
** Please also include "What you want to do" so one can also provide other possible solutions :)

What's the difference between Thread.setPriority() and android.os.Process.setThreadPriority()

If I have code like:
Runnable r = ...;
Thread thread = new Thread(r);
thread.setPriority((Thread.MAX_PRIORITY + Thread.NORM_PRIORITY) / 2);
or ...
Runnable r = ...
Thread thread = new Thread( new Runnable() {
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_MORE_FAVORABLE);
r.run();
}
});
IS the android.os.Process way required/preferred?
WHY is the android.os.Process way preferred/required if it is?
This is not clearly documented as far as I can tell.
The current Dalvik implementation seems to map Java Threads one by one to the underlying linux system PTHREADs like you say. All Threads of all apps belong to the same thread group on the system, so every Thread competes with all Threads of all apps.
So currently Thread.setPriority should actually do the same thing as Process.setThreadPriority, using the smaller Java priority scale. The mapping of priorities is defined in kNiceValues at vm/Thread.c
Google uses
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
in Volley's Network Dispatcher thread, so I would believe that using Process.setThreadPriority() is the way to go.
I would rely on thread.setPriority(). The android.os.Process.setThreadPriority names a real thread priority of the underliying linux OS. However, those could, but doesn't need to map to Dalvik / Java VM threads, as the VM could do threading on its own means or use system threads or a combination of both. Raising the system priority would more likely result in prioritizing your application in favor of others, if not restricted by android security constraints, but not guarantee prioritizing your current Java Thread in favor of other Java Threads in your application.

Categories

Resources