Callbacks to main thread without thread blocking (Java) - java

I have a program which should managing threads (create, interrupt and show working threads). And I need to notify main thread about finishing, interruption or exceptions in worker thread. Main thread should react on this events, and of course it should not be blocked. As I know it behavior released in android in handler class. But I have no idea, how it possible to do in java. Could someone help me with this problem?

If you have an event loop in your main thread, you can have a queue which it polls to see if any new events it needs to process are waiting. If you are using Swing or Android there will be an event loop already and a method you call to pass tasks to it.

Related

Understanding UI thread

For example, there are a lot of tasks are posted to UI thread as follows.
Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Some logic to display/update something in UI
}
}, 5000);
What happens to these tasks when the android application went to the background?
Will these tasks be processed even in the background? Will the complete UI thread be suspended in the background? Or? All the tasks posted to UI thread are suspended?
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
Thanks in advance.
Let's get's dirty with few terms first.
Handler:
A Handler allows communicating back with UI thread from other
background thread. This is useful in android as android doesn’t allow
other threads to communicate directly with UI thread.
In technical terms, it is a way to post Messages or runnable to your associated thread message queue.
so in total there are two task performed by handler
to schedule messages and runnables to be executed as some point in the future; and
to enqueue an action to be performed on a different thread than your own.
so how to schedule one
post(Runnable),
postAtTime(Runnable, long),
postDelayed(Runnable, Object, long),
sendEmptyMessage(int),
sendMessage(Message),
sendMessageAtTime(Message, long),
sendMessageDelayed(Message, long).
Looper:
Whatever I mentioned earlier is supported by Looper It has a loop()
method which keeps running and listening for the new messages, main thread has one running all the time so you can receive messages from another thread to this thread, if you are creating your own thread and want to listen then don't forget to call prepare() in the thread that is to run the loop.
A simple example
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
so now to answer your questions:
1: Things(Threads and so Looper and Handler) keep running until it gets finished by the user or killed by the system.
2: A looper has a loop() method that will process each message in the queue, and block when the queue is empty.
3: In case of updating the UI from background thread make sure app is in the foreground or terminate the background thread in onDestroy() you can quit the looper processing messages using handler.getLooper().quitSafely() or handler.looper.quit() if the handler is attached to the main thread.
It's recommended in case of orientation change or other configuration changes make sure to terminate the background thread.
There are many answers concerning the case. I will try to answer exactly to the questions.
What happens to these tasks when android application gone to background?
Nothing is interrupted. Handler will post a Message on MessageQueue on the specified time (unless the hosting process is killed).
Will these tasks are processed even in the background?
From the standpoint of Handler: it doesn't know whether the app is in foreground or background. All it knows, is that it should post a Message some time later.
Will the complete UI thread be suspended in background? Or? All the tasks posted to UI thread are suspended?
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
UI thread won't be "suspended" in any case (unless the hosting process is killed). It's just that it will be idle as a result of MessageQueue being empty - thus no job is needed to be done.
As a side note, refrain from performing UI related actions when app goes to background, because the state of view hierarchy won't be saved correctly. Assume you have performed textView.setText("bob") at a time, when app is in background. Now, the state of this TextView won't be saved, because onSaveInstanceState() has already been executed and won't be executed again, thus if process of the app is killed and recreated (i.e. as a consequence of system resources shortage), then the activity will be restored with a state that it had possessed when onSaveInstanceState() was called. Now user won't see "bob".
You can cancel the scheduled event using Handler#removeCallbacks() API.
UI thread is also known as the Main thread, it's a thread launched by default when you open your application and where all your interactions happen unless you offload them to some other thread. It's not dependent on the visibility of the app, it's running as long as the app lives. It's not suspended by the system.
What happens to UI thread when there are no tasks posted to it after the activity is completely loaded? Will it be suspended, if there are no tasks are in the Looper?
Let's start with the Looper concept. It's very important for understanding how UI thread is working. Looper is a thing that loops in a given thread and handles incoming messages, when there are no tasks it's looping and waiting for new tasks, so, answering your last question, the thread will not be suspended. Looper is designed to keep the thread alive even when there are no tasks. UI thread in Android has it's own Looper by default.
What happens to these tasks when android application gone to background?
Will these tasks are processed even in the background? Will the complete UI thread be suspended in background? Or? All the tasks posted to UI thread are suspended?
Going to background does not change anything for the main thread. It's running until the application is killed. So your code scheduled on a handler will just run.
On a side note. The possible problem here is that while activity is in the background it can be killed by the system and you attempt to change UI of it will crash the app (there are a few similar scenarios), but it's not really related to the UI thread.
All in all, the UI thread is not suspended by the framework under any conditions. It just runs and processes everything you give it or waits until new tasks are given to it.
Here you can find the description of the main thread in the official docs.
This is a good SO thread about looper.
What happens to these tasks when android application gone to
background?
It will work as intended, No change in the behavior of UI Changes. Only thing is we are not able to see those changes.
Best Solution:
Update any view inside your handler when app is in background
eg: TextView and set some text in it, and get this TextView value once the application goes in the foreground.
Will these tasks are processed even in the background? Will the
complete UI thread be suspended in background? Or? All the tasks
posted to UI thread are suspended?
As I mentioned above this task will work as it is.
The application does not change UI thread when you move to the background, It will remain as it is.
What happens to UI thread when there are no tasks posted to it after
the activity is completely loaded? Will it be suspended, if there are
no tasks are in the Looper?
Putting it simply, there are Looper threads, for example, UI thread. Such thread has its own Looper, which runs a message loop for the thread. Once message queue is finished it will be finish itself.
UI thread will not be suspended at any cost by itself, Until and unless you write some code to change it :).
Nice to read:
Androids Handler.post, what happens exactly
What is the relationship between Looper, Handler and MessageQueue in Android?

What happens to the main application thread?

As far as I know, there are 3 threads in a Swing GUI application:
the main application thread, which executes the main() method
the toolkit thread, which receives the system events
the event dispatching thread, dedicated to the painting and event handling of the GUI stuff
Generally, the main method just makes a call to SwingUtilities#invokeLater(Runnable) in order to initialize a window and so on, thus the GUI initialization is made on the EDT... BTW, as far as I know (again), everything that touches the GUI must be executed on the EDT...
Questions: What is the main thread used / usable for? Does it just die after the call to invokeLater()? Does it consume resources? Can I (and is it a good practice to) use it to perform... I don't know... Network stuff?
A Swing programmer deals, actually, with 3 kinds of threads:
Initial threads (the one that executes the initial application code,
our main here)
The EDT (as you metioned)
Worker threads (to deal with background tasks)
The inital thread creates the Runnable to run swings tasks and schedule it in the EDT. After that, the program is primarly driven by the GUI, and the application code survives and can continue to execute other tasks (Network staff as you noticed) and consumes resources as much as it needs.
Any Swing component method must be invoqued by the EDT (but some of them) because they swing method are not "thread-safe". So,
SwingUtilities#invokeLater(Runnable)
just queues the runnable in the EDT task list and wait for its turn to run.
The doc here is quite helpful.
The main thread in a Java program dies when control reaches the end of main().
In the program architecture that you describe, the main thread already has created the EDT and maybe other threads by that point, and those other threads keep the JVM alive.
Every thread in Java is either a daemon thread, or a non-daemon thread. The latter is the default case for a new Thread. You have to call t.setDaemon(true) if you want a daemon.
A JVM will keep running as long as there is at least one non-daemon thread still alive.
What is the main thread used / usable for?
It is usable for any purpose that you would use any other thread for. It executes whatever code you write for it to execute.

How to monitor Event Dispatch Thread queue?

I have a heavy java project which does not work responsive to the users. I have found out that long time needed events in event dispatch thread can cause my project to work slowly. So, I have two question in this manner:
How can I monitor the event dispatch thread and see which events are in the queue and eventually, which ones spend more time in event dispatch thread? ( As you know invokeLater function insert the event to the end of the event dispatch queue. I want to monitor whole event dispatch queue)
How can I insert an event to the first of the event dispatch thread? (in this case, the GUI will be responsive).
Typically the slowness is caused by code that inadvertently tries to access the filesystem, network or database from the UI thread. Its usually pretty easy to fix with SwingWorkers once the cause has been identified.
Replace the Event Dispatch Queue with an implementation that monitors how long events in the queue take to process.
When an event takes too long the new queue implementation logs the stacktrace of the EDT.
If you are only used to looking at stacktraces when exceptions are thrown don't get alarmed. The new implementation isn't killing slow events or causing them to throw exceptions its just showing you what the EDT is doing at the moment when the unresponsiveness was detected.
Look at the printed stacktraces and figure out how to move the slow part of the event into another thread.
I believe Netbean's slowness detector implements something very similar.
You need to provide more details...but thread themselves don't have queues. You can not check to see what work is waiting on a thread, you can only check the status of any given thread (say in a thread pool).
If you have a concept of "work" that needs to be queued for eventually processing by a given "worker" (ie thread) you have to implement that yourself. Alternatively you can use a an actor system such AKKA which sounds like it would do what you require

Android -Activity - Thread Basics

I am still confused at threads. Still I could see some answers which points to threads, UI thread, background thread, main thread etc. (mostly on AsyncTasks and updating UI from background threads etc.)
Could anyone give me a complete explanation around these or some links at least?
It would be great if the answer covers the following cases:
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
An activity with AsyncTask
A Background Service
A HTTP call
UI thread (main thread) - it is crucial to instantiate (add) all UI elements on this thread, that is why it has a nickname UIThread
AsyncTask - has methods doInBackground, onPostExecute, etc. Sort of its own lifecycle
Background Service (service) A service runs by default in the same process as the application. in its own thread. (as pointed out by #MisterSmith) A service runs by default in the same process as the application. in its own thread. Therefore you need to use asynchronous processing in the service to perform resource intensive tasks in the background. Services which run in the process of the application are sometimes called local services.
Thought you can specify to run a Service in its own process:
Running a service in its own process will not block the application in case the service performs long running operations in its main thread. But as the services runs in its own process you need to use some interprocess communication (IPC) to communicate to your service from other parts.
HTTP call executed using HttpClient (from docs:
Thread safety of HTTP clients depends on the implementation and
configuration of the specific client.
), has to be executed on non-UI thread by using new Thread(new Runnable(...)).start();, otherwise you will get NetworkOnMainThreadException thanks to #vikram. But it seems that HttpClient.execute() method is executed in a thread, that is why it requires a handler as one of the parameters in order to pass the result to the corresponding handler (handler runs on UI thread and can update widgets (UI elements) as it is needed)
Extra:
To force something to be executed on your main thread use yourContextInstance.runOnUiThread(new Runnable(....));
In order to determine if current thread is UI(main) thread:
Looper.getMainLooper().getThread() == Thread.currentThread();
Interesting question about threads in a service:
Does a runnable in a service run on the UI thread
Why UI thread is responsible for all this?
Because UI thread is in charge of dispatching the events to the
appropriate widgets (UI elements), which includes the drawing events
Sources: this that and a little bit of that and some of that
When I am running an activity ( seting a content view , attaching some buttons, some dialog messages )
Usually only one thread (the main one, sometimes incorrectly called UI thread).
Activity - with async task
Again, by default only one (the main one). Menus and button handlers also run in the main thread. AsyncTask is a different story. It creates a worker thread (btw you should be careful not to leak it when exiting the activity).
Background Service
A service runs by default in the main thread. So do broadcast receivers. And this is why the main thread is not (only) the UI thread. Some types of services (like the popular IntentService) spawn a worker thread though.
An http Call
Is a synchronous operation, so it blocks until it completes (and this is why you should never perfom one in the main thread).
Technically speaking an application can have as many threads as it wants, they are arbitrarily created by the programmer.
However, the standard android application by default has one thread. That is the main thread, and is often referred to as the UI thread (as it is the only thread with access to the UI). By default everything happens in the main thread.
If you run an async task, different parts run in different threads, here's a basic breakdown:
onPreExecute() runs in the UI thread and is first called when you execute an async task.
doInBackground() runs in a newly spawned thread separate from the main/UI thread.
onPostExecute() runs in the UI thread after the background task returns.
A background service runs entirely separately from the application, it can run indefinitely even if the original application is destroyed.
An http call happens on whatever thread you call it on, but as a requirement of newer android API's you can no longer do any network activity from the main/UI thread. (This will actually cause an exception and terminate your application) This is to prevent slow network calls from blocking the main thread and therefore creating a choppy user experience.
Which are all the threads that's involved:
When I am running an activity (setting the content view, attaching some buttons, some dialog messages)
UI Thread or Main Thread is involved here.
An activity with AsyncTask
Both UI Thread and WorkerThread is involved.
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
doInBackground(Params...), invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. This step can also use publishProgress(Progress...) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress...) step.
onProgressUpdate(Progress...), invoked on the UI thread after a call to publishProgress(Progress...). This method is used to display any form of progress in the user interface while the background computation is still executing.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
A Background Service
The IntentService class provides a straightforward structure for running an operation on a single background thread. This allows it to handle long-running operations without affecting your user interface's responsivenes
A HTTP call
NetwokrkOperation can't be executed from UI Thread ( or MainThread). So use alternatives like AsyncTask or HandlerThread
Related posts:
Handler vs AsyncTask vs Thread
Why use HandlerThread in Android
Asynctask vs Thread vs Services vs Loader

Android - Thread.sleep and Handler.postDelayed() freezes animated UI elements

In my activity, my app downloads a list of something from a website via an Http Connection. Before this list of things is displayed on the screen, I have a Loading... TextView with a little spinning ProgressBar to indicate that the data is currnetly being downloaded.
I noticed, that if I do any type of Thread.sleep() during the process of fetching the data from the web, it freezes the spinning ProgressBar.
Even if I put the method in it's own Handler Runnable so that it's on it's own thread, the animation freezing still occurs.
Is there anything I can do about this?
Yes, use AsyncTask.
A Handler is usually attached to the UI thread. Posting Runnables to it doesn't change the fact that they will run on the UI thread.
Any application should do long running tasks on a seperate thread to the UI thread as any blocking calls will not allow the UI to update.
As the other poster said, using Runnables alone do not mean the code will be executed on a seperate thread. In this case the run() method will execute on whatever thread your Handler object was created on. Either subclass Thread or pass your runnabe to new thread object with public Thread (Runnable runnable).
Using AsyncTasks, Loaders or Threads will help.
Also read Designing for Responsiveness and Multithreading For Performance. Following the above approaches will help you avoid ANRs
The reason for such a behaviour is that:
When you do thread.sleep() inside a runnable, it is the UI thread which executes that runnable rather than the respective other thread which you created. Basically what happens is that when you post any runnable through the handler of the UI thread, UI thread will poll from its queue and execute the runnable; in this case the runnable will do sleep.
Hence no change in progress bar

Categories