Task queue on Android like in GCD on iOS? - android

Is there such a thing as task queue on Android? I know that it can be written by hand but is there a ready to use library for that?

I'm not sure if there would be a library for this one, as Android already provides the high-level building blocks for what you're trying to achieve.
Handler
If I understood you correctly, you want to post tasks from any thread to be queued and executed one-by-one on a dedicated thread. This is very much what Android Handler is meant for.
Key traits of Handler, Looper and MessageQueue
A Handler is tied to a single Looper.
Each Looper has an associated MessageQueue
Handler uses a Looper underneath to enqueue and dequeue messages in a thread-safe manner into the Looper's MessageQueue.
Handler objects are inherently thread-safe and hence can be passed around to other threads safely.
You can have multiple Handler objects tied to a same Looper. This is useful if you want to process different kinds of messages using different Handlers. In this case, you are guaranteed that only one of the Handlers will process a Message/Runnable for a given Looper. The Looper takes care of dispatching the Message to the right Handler.
If you're already familiar with the Message Queue paradigm for communicating between 2 threads (or similar golang's buffered channel pattern), Handler is just a high level class which lets you use this pattern easily.
Example for using Handler to send/receive Messages, post Runnables
// BEGIN One-time Initialization
// Create a Handler thread
// This provides the looper for the Message Queue and
// will be processing all your messages (i.e. tasks).
handlerThread = new HandlerThread("SomeThreadName");
// Start the Handler Thread
// The thread will block (using the looper) until it
// receives a new message
handlerThread.start();
// Create a Message Handler which you can use to
// post and process messages
// The same Handler can also be used to post a Runnable which will get
// executed on handlerThread
handler = new CustomHandler(mHandlerThread.getLooper());
// END One-time Initialization
// Different ways to post a message to the Handler Thread
// These calls are thread-safe, can be called safely and
// concurrently from multiple threads without race conditions
handler.sendEmptyMessage(MESSAGE_ID_1);
handler.sendEmptyMessage(MESSAGE_ID_2);
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_3, obj1));
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_4, value, obj1));
handler.sendMessage(handler.obtainMessage(MESSAGE_ID_5, value1, valu2, obj1));
// Post a runnable on the Handler Thread
// This is thread-safe as well
// In fact all methods on the Handler class are thread-safe
handler.post(new Runnable() {
#Override
public void run() {
// Code to run on the Handler thread
}
});
// A skeleton implementation for CustomHandler
// NOTE: You can use the Handler class as-is without sub-classing it, if you
// intend to post just Runnables and NOT any messages
public class CustomHandler extends Handler {
public CustomHandler(Looper looper) {
super(looper);
}
#Override
public void handleMessage(Message message) {
if (message != null) {
// Process the message
// The result can be sent back to the caller using a callback
// or alternatively, the caller could have passed a Handler
// argument, which the Handler Thread can post a message to
switch (message.what) {
case MESSAGE_ID_1:
// Some logic here
break;
case MESSAGE_ID_2:
// Some logic here
break;
case MESSAGE_ID_3:
// Some logic here
break;
case MESSAGE_ID_4:
// Some logic here
break;
case MESSAGE_ID_5:
// Some logic here
break;
// Add more message types here as required
}
}
}
}
// After you're done processing all messages and you
// want to exit the Handler Thread
// This will ensure that the queue does not accept any
// new messages, and all enqueued messages do get processed
handlerThread.quitSafely();
Deviations from the above example
Although I've used HandlerThread in the above example, it is not mandatory to use it. You can even use the Looper calls directly, i.e. Looper.prepare() and Looper.loop() to run your own message loop in a thread.
As already mentioned in the comments, you do not need to sub-class the stock Handler if you do not intend to handle any messages.
You can communicate between multiple threads easily by using a Handler for each thread that needs to receive the message.
There are methods in Handler to schedule message delivery and Runnable execution in the future as well.
Android's framework internally uses Handler extensively for managing component lifecycle events (onPause, onResume, etc.).
AsyncTask
AsyncTask is another alternative to scheduling tasks on a different thread. . I won't go into too much detail of its implementation, as the Android developer documentation already describes it in detail.
I usually use AsyncTasks for tasks that I know I'll use a background thread for a long time (easily >= 100 ms at least). Some examples which fall into this category I can think of are Binder IPC, RPC calls, Network calls, Background downloads, etc.
On the other hand, Handler is more tailored for situations focussed on processing more number of messages as quickly as possible. In other words avoid performing any blocking operation in handleMessage(). You can write lock-free code easily using Handler, it manages all the locking for you when enqueuing and dequeuing messages.
In fact AsyncTask can be used in combination with Handler by splitting the work into a fast part (taken care by Handler) and a slow part (taken care by AsyncTask).
PS: Although tangential to the question, if you're interested in the Message Queue paradigm; do take a look at LMAX Disruptor, which is a high performance inter-thread Message Queue library. Their design document explains pretty well, which parts of the Message Queue, need locking/atomic access.

I've also looked around for something like GCD for Android. While Handlers and AsyncTasks are awesome the beauty of GCD (in my humble opinion) is that you can dispatch a workload on a background thread to do the heavy lifting. When the execution is done it i easy to execute the UI updates on the UI thread.
Since I did not find anything me and my school mate decided to create one of our own.
You can find it at:
ICDispatch on github
Basically all you need to do is to declare an Application class that extends ICDispatchApplication instead of Application and when you want to dispatch something you just call on
App.executeOn(int queue, ICBlock block);
Example:
App.executeOn(ICDispatch.NORMAL, new ICBlock(){
public void run(){
//do stuff...
App.executeOn(ICDispatch.MAIN, new ICBlock(){
public void run(){
//post result to UI thread.
}
}
}
});
The worst part is that there will be a lot of indentation. In order to minimize indentation you could use lambda notation:
App.executeOn(ICDispatch.NORMAL, ()->{
//do stuff...
//do some more...
//then even more
App.executeOn(ICDispatch.MAIN,() -> {
//Post result on UI thread.
}
});
At the moment ICDispatch supports LOW, NORMAL, HIGH, MAIN and CONCURRENT queueing. Features will be added as they are implemented.

I don't know iOS so I'm not sure if it is the same but in Android you have the ScheduledThreadPoolExecutor

For anyone finding this thread now, there is a new framework available called Bolts. It has tasks and continuations and can wait on multiple tasks to finish, like GCD.

I take this sample from Telegram Code :
You can declare extended thread for this approach
public static volatile DispatchQueue globalQueue = new DispatchQueue("globalQueue");
the class is :
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import java.util.concurrent.CountDownLatch;
public class DispatchQueue extends Thread {
private volatile Handler handler = null;
private CountDownLatch syncLatch = new CountDownLatch(1);
public DispatchQueue(final String threadName) {
setName(threadName);
start();
}
private void sendMessage(Message msg, int delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.sendMessage(msg);
} else {
handler.sendMessageDelayed(msg, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cancelRunnable(Runnable runnable) {
try {
syncLatch.await();
handler.removeCallbacks(runnable);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void postRunnable(Runnable runnable) {
postRunnable(runnable, 0);
}
public void postRunnable(Runnable runnable, long delay) {
try {
syncLatch.await();
if (delay <= 0) {
handler.post(runnable);
} else {
handler.postDelayed(runnable, delay);
}
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
public void cleanupQueue() {
try {
syncLatch.await();
handler.removeCallbacksAndMessages(null);
} catch (Exception e) {
FileLog.e("tmessages", e);
}
}
#Override
public void run() {
Looper.prepare();
handler = new Handler();
syncLatch.countDown();
Looper.loop();
}
}
and the Caller :
globalQueue.postRunnable(new Runnable() {
#Override
public void run() {
/* do here what you want */
}
});

You should check Handler & Loopers
Handlers, by default (*), like dispatch_get_main_queue() and you can post any block (Runnable instance) of code. Same approach also acquired with Context.runOnUiThread() and View.post(Runnable)
(*) Default constructor of Handler inherits the current thread's Looper instance (RunLoop in iOS) and queues (via handlerInstace.post...() methods) Runnable instances on Looper.
For more advance usage. You can create your own Looper instance (be aware it is a bit tricky :)). Still this might be handy...
Also for more advance usage, Handlers are the best tools i come across on Android (and yes, i miss them on iOS) for messaging inside application (inter-process communication something i guess). They might be customized to handle posted messages, bla, bla...

Related

Why do we use a Handler? Why we don't call an interface element inside a Runnable object?

Whenever this code is executed the application crashes, but when a handler is used the application works as expected.
Runnable r = new Runnable() {
#Override
public void run() {
long futuretime = System.currentTimeMillis()+10000;
while(System.currentTimeMillis()<futuretime){
synchronized (this){
try {
wait(futuretime - System.currentTimeMillis());
} catch (Exception e) {}
}
}
//this code needs to be inside a Handler ??
TextView time = (TextView)findViewById(R.id.timedisplay);
time.setText("Changed Man!!");
//this code needs to be inside a Handler ??
}
};
Thread thread = new Thread(r);
thread.start();
}
Here all the answer have mentioned use of handler is used in Android with UI thread. But Let me add more to it.
If you have gone Android documentation/tutorial you would know that
When an application component starts and the application does not have
any other components running, the Android system starts a new Linux
process for the application with a single thread of execution. By
default, all components of the same application run in the same
process and thread (called the "main" thread or uiThread).
for more info refer
Now coming to your mentioned example; you have created another thread using Runnable...so there might be scenario you need thread(s) other then just mainThread in Android Application.
If you are good in JAVA Threading concept then you would know how Interthread communication happens and for different ways how it can be done refer
So coming back to question in android we have mainThread or uiThread so called which holds our ui i.e. view component. These component are private to mainThread so other thread cannot access it...which has been mentioned in previous answer. This is where Handler comes into picture you do not need to worry how your message would be passed from one thread to another.
Handler
There are two main uses for a Handler: (1) to schedule messages and
runnables to be executed as some point in the future; and (2) to
enqueue an action to be performed on a different thread than your
own.When posting or sending to a Handler, you can either allow the
item to be processed as soon as the message queue is ready to do so,
or specify a delay before it gets processed or absolute time for it to
be processed. The latter two allow you to implement timeouts, ticks,
and other timing-based behavior.
For more info refer docs AND
For more info with handler and UI thread
Code that deals with the UI should be run on the UI (main) thread.
You (probably) create a handler on the UI thread, so all messages sent via it will run on that thread too.
The Runnable is use for background process(background thread) and textview is in your UI thread so background thread can't communicate with foreground thread so it will gives you error and crashes your application.you can also use the runOnUiThread. example.
Runnable r = new Runnable() {
#Override
public void run() {
long futuretime = System.currentTimeMillis()+10000;
while(System.currentTimeMillis()<futuretime){
synchronized (this){
try {
wait(futuretime - System.currentTimeMillis());
} catch (Exception e) {}
}
}
try {
// code runs in a thread
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView time = (TextView)findViewById(R.id.timedisplay);
time.setText("Changed Man!!");
}
});
} catch (final Exception ex) {
Log.i("---","Exception in thread");
}
}
};
Thread thread = new Thread(r);
thread.start();
The reason why your app crashes is that you modify View from a non-UI thread.
If you do it using a Handler that belongs to UI-thread this works as expected.Update
If you need to run Runnable to modify UI you may choose from:
1) yourActivity.runOnUiThread(Runnable r)
2) yourHandlerOnUIThread.post(Runnable r)
3) yourView.post(Runnable r)

Java Android Native thread issues

I have one thread that does lot of time consuming tasks. The tasks are being done in the native part in c++. I would like to cancel the operation that is being done in the native, the code for that is place. I can reset everything.
mWorker = new WorkerThread("Worker thread");
mWorker.start();
//From Main thread:- Interrupting
mWorker.interrupt();
if(mWorker.isInterrupted()) {
Log.i(MOD_TAG, "Worker thread is interupptedd!!! ");
}
//Worker thread
public class WorkerThread extends Thread implements Runnable{
public void run() {
while(!Thread.currentThread().isInterrupted()) {
Looper.prepare();
mHandler = new WorkerHandler();
Looper.loop();
}
class WorkerHandler extends Handler {
#Override public void handleMessage(Message msg) {
try {
switch(msg.what) {
//do something native code
}
}
catch (Exception e) {}
}
}
}
}
Even if the workerthread is interrupted I cannot send any message to the worker thread while the worker thread is doing processing. Can I do something to post a message to workerthread or do something else that could let me call a native method within the same thread.
In your example, I don't understand what that Handler is doing inside the Thread. Once you call loop() within the run, that call will block until the looper is stopped via quit() or quitSafely(). The call is basically just a loop which reaps a queue for messages. Your check for interrupt will never happen.
I would recommend something like this. If you want your code to be managed by a handler you would do something like:
HandlerThread handlerThread = new HandlerThread("NativeHandler");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper()) {
public void handleMessage(Message msg) {
someObject.callNativeLongRunningFuction();
}
};
However interrupt still won't do anything because the looper only handles one message at a time. So if it is stuck handling callNativeLongRunningFunction(), that is not going to help you really either. If you want to have interrupt stop the ongoing execution of the jni call, the I don't think this approach will work at all with the given information. Interrupt in java only sets a flag and when there is a call to wait(), it will throw an exception when that flag is checked and also set. But for a jni call there isn't a call to wait(), the java stack is sort of blocked but it is not in the middle of a wait() either. So unless you check interrupted within the native runtime, that function will continue to run. Overall I am guessing this probably would not be what you really want.
If that is so, I would recommend something like this instead.
public class NativeThreadTask {
public native void start();
public native boolean isRunning();
public native boolean cancel();
}
Inside the native implementation of that class, you would then use a pThread to call your native long running function. Start and Cancel would manipulate that pThread which would run the expensive function in a separate thread. Using pthread_cancel you can interrupt that pthread instance too. This moves the long operation off your thread and out of your runtime, while still allowing you to control when the pthread interrupt mechanism is invoked but over the jni bridge. If you don't even want to interrupt and if the long running native call is iterating over a large amount of data, then it might be worthwhile to have cancel() simply change bool that is evaluated within each iteration of the native function's loop.
So with the given example you could probably do something like this.
NativeThread nativeThread = new NativeThread();
Handler handler = new Handler() {
public void handleMessage(Message message) {
NativeThread nativeThread = (NativeThread)message.obj;
switch(message.what) {
case 0:
if (!nativeThread.isRunning()) {
nativeThread.start();
}
break;
case 1:
if (nativeThread.isRunning()) {
nativeThread.cancel();
}
break;
default:
}
}
};

Having a long running service in its own task for networking

so my intentions is the following:
I need a background service that mainly takes send requests (UDP) from the main UI and waits for its responses which in turn are dispatched back to the main UI. This is a pretty synchronous process. But additionally, I want the Service to wait for asynchronous messages that can be received any time over the network, for example a network client wants to notify me or to report an error.
What would be the best way to implement this?
Well for IPC the Messenger class could be useful to handle data.
Could it be implemented like the "Remote Messenger Service Sample" found here http://developer.android.com/reference/android/app/Service.html ??
Any help is appreciated.
In my project, i have a service that is permanently running.
I have also 3 threads created in this service, so all in background. Each one of them does some work, requesting http data also: i've done it with the Handler, managing the message queue.
It's easy and grows well, growing the dimension and complexity of project.
So, yes, i should follow that way.
P.S.: If you have to do work in background, remember to acquire wake_locks with PowerManager, ensuring you that CPU will stay on when phone goes in standby (it tooked me some days to understand why threads stop to work when phone goes in standby).
In the main thread, i declared the 4 handlers (2 for two-side communication with recordingThread, and 2 for two-side communication with sendingThread):
Then simply create the other 2 threads; look at Looper calls: it's needed to do not let your thread to die when the code is executed, and to wait for incoming messages coming on handlers created inside its own execution (in this case inside the run() method).
I've also declared a private class for each handler associated to a thread: this way every thread has its own channel to communicate with different 'action' to do (the switch cases).
There's also the other handler, the recordingThread handler, not shown here; but the idea is the same:
private Handler m_recordingThreadHandler, m_sendingThreadHandler,
m_thisRecordingThreadhandler, m_thisSendingThreadHandler;
public void run() {
Looper.prepare();
m_thisRecordingThreadhandler = new UpdRecHandler();
m_recordingThread = new RecordingThread(m_mainThreadContext,
m_thisRecordingThreadhandler, m_configuration, m_picturesDir);
m_recordingThread.setName("recordingThread");
m_recordingThread.start();
m_thisSendingThreadHandler = new UpdSenHandler();
m_sendingThread = new SendingThread(m_mainThreadContext,
m_thisSendingThreadHandler, m_configuration);
m_sendingThread.setName("sendingThread");
m_sendingThread.start();
Looper.loop();
}
private class UpdRecHandler extends Handler {
#Override
public void handleMessage(Message msg) {
Message m;
switch (msg.what) {
case Utils.SEND_THIS_THREAD_HANDLER:
Log.i(TAG, "Ricevuto Handler di recordingThread.");
m_recordingThreadHandler = (Handler) msg.obj;
m_recordingThreadReady = true;
checkForAllThreadsReady();
break;
case Utils.FORCE_RESET:
Log.i(TAG,
"RecordingThread ha compeltato la procedura per il reset.");
m_recordingThreadResetted = true;
checkForThreadsResetted();
break;
...more cases...
}
This code is instead from recordingThread class.
Once created, the run method is executed, in which i pass to the main thread (the code previously seen) the handler of this thread, created in this run() method: in this way i enable 2-sided communication.
Again, in the recordingThread i create a private class for the handler. And again i've put the Looper calls to let thread be alive once run method is executed.
public void run() {
Looper.prepare();
Log.i(TAG, "In esecuzione, mando il mio handler a updateThread");
m_thisThreadHandler = new RecUpdHandler();
m_mainThreadHandler.obtainMessage(Utils.SEND_THIS_THREAD_HANDLER,
m_thisThreadHandler).sendToTarget();
Looper.loop();
}
private class RecUpdHandler extends Handler {
public void handleMessage(Message msg) {
Message m;
switch (msg.what) {
case Utils.TAKE_PHOTO:
...do work....
break;
case Utils.UPDATE_CONFIGURATION:
... do other work...
break;
}
If you want to let your thread terminate, you have simply to kill the Looper associated to that thread, doing as follow:
Looper.myLooper().quit();
And remember that an handler is associated automatically to the thread in which it's created: if handler A is created in thread T1, then you can pass a reference of A to T2 and T3. Those thread are then capable of send messages to T1, but not viceversa.
That's because i've created 4 handlers, for enabling 2-side communication.

Specifics on using Looper.prepare() in Android

I'm having a bit of trouble understanding how to use the Looper prepare()/loop()/quit() logic.
I have three threads: one is the UI thread, one is a game logic thread and the last is a network communication thread (a background thread, lives only while being used).
The game thread has many dependencies on the results of the network calls, so I wanted to spin the network thread off of the game thread and have a Handler post the result back.
Of course, since the UI thread is not involved I need to call Looper.prepare()... somewhere. I thought it should be called in the game thread, but I can't do that because loop() takes it over.
How do I go about posting back to the game thread from network thread with my handler?
What's going on is that once you call Looper.prepare() followed by Looper.loop() on a Thread, all that Thread will ever do is service its MessageQueue until someone calls quit() on its Looper.
The other thing to realize is that, by default, when a Handler is instantiated, it's code will always execute on the Thread it was created on
What you should do is create a new Thread and in run() call Looper.prepare(), setup any Handlers, and then call Looper.loop().
Bearing these things in mind here is the basic pattern I use a lot of places. Also, there's a good chance you should just be using AsyncTask instead.
public class NetworkThread extends Thread {
private Handler mHandler;
private Handler mCallback;
private int QUIT = 0;
private int DOWNLOAD_FILE = 1;
public NetworkThread(Handler onDownloaded) {
mCallback = onDownloaded;
}
public void run() {
Looper.prepare();
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
// things that this thread should do
case QUIT:
Looper.myLooper().quit();
break;
case DOWNLOAD_FILE:
// download the file
mCallback.sendMessage(/*result is ready*/);
}
}
}
Looper.loop();
}
public void stopWorking() {
// construct message to send to mHandler that causes it to call
// Looper.myLooper().quit
}
public void downloadFile(String url) {
// construct a message to send to mHandler that will cause it to
// download the file
}
}
Could you tell some examples for what you are using your network thread? I think you can solve your problems without using Looper.
You can use ASyncTask to perform background task that may update some values in your UI thread. If user has to wait until background operation will be finished, you can show ProgressDialog and block application in OnPreExecute method, and then hide it in onPostExecute.
As I said, please describe more your needs and target which you want to achieve.

get main thread's message queue and handler

How do I get the message queue of the main thread from another thread? Looper.getMainLooper() gets the main thread's looper but I am unable to find a way to get the MessageQueue for another thread's looper. Moreover, how do I get the handler for the main looper? I am unable to find any way to get it.
#r.v,
I had a similar need. I wanted to know when the MessageQueue is empty and when I post something for it to do and I want to know when it becomes empty with nothing remaining to do. I looked at the MessageQueue.IdleHandler and found that it didn't behave as I wanted to I came up with another solution.
In my case I wanted to use the Looper/Handler mechanism to sequentially execute file downloads. Basically each download I want to execute is wrapped in a Runnable. I only want one at a time to be running, so this pattern works well without having to dig into the nuts and bolts of a more involved threading solution. Additionally, I wanted to know when I first put something into the queue and it begins its work, and wanted to know when it was completely done (queue is empty).
I was able to use the handler's message mechanism to achieve this. The messages are handled in sequence with the Runnables, so you can strategically place messages in the queue to help you know the conditions of the queue. Unlike with Runnables in the Handler's queue, there are some query and removal abilities for messages that ultimately provide the solution.
What I do is each time I add a runnable to the Handler (via Handler.post), I also remove all instances of the custom QUEUE_EMPTY message, then add a fresh QUEUE_EMPTY message. This ensures that I have a QUEUE_EMPTY message at the end of the queue. Once I encounter the QUEUE_EMPTY message in my subclassed Handler, I know that I'm at the end of the queue. Additionally, if I don't find a QUEUE_EMPTY message in the queue when I go to add a runnable, I know that the queue was empty and the thread was idle.
As some will quickly point out, there are some real inefficiencies with this solution. Having to iterate through the queue for these "marker" messages could be a real performance issue if there were a large number of entries in the queue. In my case, I'm dealing with only a handful of file downloads at a time so any performance penalties are negligible. If you have a similar situation, I think this is a pretty reasonable solution. It would have been nice for the Android SDK to provide these basic abilities to the MessageQueue. I agree ideally you wouldn't want to mess with the MessageQueue, but knowing when it is idle/working/empty seem like reasonable things and I'm sure there are numbers of scenarios when there is value knowing these things.
class DownloaderThread extends Thread
{
private static final int QUEUE_EMPTY = 9999;
private MyHandler handler;
#Override
public void run()
{
try
{
Looper.prepare();
handler = new MyHandler();
Looper.loop();
}
catch (Throwable t)
{
Log.e(TAG, "halted due to an error", t);
}
}
public void post(Runnable r)
{
if(!handler.hasMessages(QUEUE_EMPTY))
{
Log.v(TAG, "Download queue was empty. First element being added.");
}
handler.post(r);
handler.removeMessages(QUEUE_EMPTY);
handler.sendEmptyMessage(QUEUE_EMPTY);
}
class MyHandler extends Handler
{
#Override
public void handleMessage(Message msg)
{
if(msg.what == QUEUE_EMPTY)
{
Log.v(TAG, "Download runnable queue is empty!");
}
}
}
};
After you get the main threads looper, you should just be able to call myQueue to get the main threads MessageQueue.
http://developer.android.com/reference/android/os/Looper.html#myQueue%28%29
Use the Handler class to interact with a Looper's message queue.
To interact with the main thread's message queue,
Handler mainHandler = new Handler(Looper.getMainLooper(), new Callback() {
#Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
}
});
mainHandler.post(...);
mainHandler.sendMessage(...);
mainHandler.removeMessage(...);
Now you can send, remove and receive messages.

Categories

Resources