Waiting for thread to finish without blocking UI thread - java

Im running a Thread inside methode and i want to return a value once the thread finish, the problem that i tried to do join() but that blocks the UI thread.
How could i wait for the thread to finish and then return the value without blocking the UI thread ?
Boolean foo(){
myThread mt = new myThread();
mt.start();
return mt.isSentSuccessfully;
}

You can use Android's AsyncTask for that.
http://developer.android.com/reference/android/os/AsyncTask.html
When I use it, I put the background task in a class that extends AsyncTask and overwrite the onPreExecute() and onPostExecute(..) methods to show/hide the ProgressDialog. It works quite nicely.

If you really don't want to use the AsyncTask, then you might like to define a Handler
then in your background thread send a message to the main thread when the background job finishes with something like:
ActivityMainThreadClassName.this.myUpdateHandler.sendMessage(m);
where myUpdateHandler is the handler you created.

Did you try polling Thread.getState()?
Something like this:
android.os.Handler h = new Handler();
h.postDelayed(new Runnable() {
public void run () {
if (thread.getState() == Thread.State.TERMINATED) {
// your code here
return;
}
h.postDelayed(this, 1000);
}, 1000);
This sample should poll a thread state every second... (I didn't tested it)

Related

Java - are there different ways of starting threads?

Ok, guys so my teacher uses this code to start a thread if a thread is not already active. But i have been taught that to run threads no matter if its runnable or extending thread, you start it by the start method and not run. But in this case he starts it with run, why is that?
public void start2(Runnable r) {
if (thread == null) {
thread = new Thread(new Runnable() {
public void run() {
r.run();
thread = null;
}
});
thread.start();
}
}
Your teacher starts thread with thread.start() . He just implemented the runnable interface inside the Thread object initialization which is the absolutely correct approach.
A more modern approach would be to use an Executor to run the thread:
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
});
You have a better control of the thread:
Can retrieve some result (with futures)
Know if your thread is over (executor.isTerminated())
Request/force a shutdown (executor.awaitTermination()/executor.shutdownNow()).
These functionalities are not natively supported by the thread.start() that your teacher shows you (which is, by the way, a good way to launch a thread).
For more about Executors, I advice this excellent tutorial.
The r.run(); part in your code is just a method call to your Runnable r input parameter, which will be an implementation of the Runnable interface.
This does not start a thread
It's just a method call that is executes the input's implementation of Run method.
It will execute just like any other method.
Then, the actual thread will start at thread.start();
Long answer:
What is happening here is, first checking the thread variable.
If its null then initialize a new Thread with an anonymus class thread = new Thread(/*here --> */new Runnable() {.... and implementing the run() method.
Inside the run() there is a call, made to the outer method's input param, called Runnable r with r.run(); then set the thread variable to null.
Just outside of the if statement, the teacher starts the thread with thread.start();.

Timer class in android or a Handler timer? [duplicate]

This question already has answers here:
What is the different between Handler, Runnable, and Threads?
(6 answers)
Timertask or Handler
(3 answers)
handler or timer android
(3 answers)
Closed 4 years ago.
What is the difference between Android timer class and creating one with a Handler?
i tried both ways and i understand they can do different things but i dont know why,for example with android timer class i cant update views and i think that is a huge limitation,but with a handler the code feels messy.
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//actions
}
}, 2000);
}
So,what is the best to do a action every tot seconds?
Edit:this isnt a duplicate because im asking about updating views with timers.
android.os.Handler is part of Android framework, the job will execute on the UI or main thread if you have created the Handler in the UI or main thread. Note that in Android you can only update views from the UI thread.
java.util.Timer on the other hand will execute on another thread so it cannot update the views.
So Handler is the recommended here. If you really want to use Timer you have to use runOnUiThread like:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
//this will run on UI thread so you can update views here
}
});
}
}, 2000, 2000);
According to this answer : Android - Timertask or Handler , you're right about TimerTask class not being able to update views (cannot update the UI Thread).
Definitely opt for Handler. The syntax looks clean to be honest.
In my experience, Handler and the corresponding Android helper class HandlerThread are very flexible and allow you to do just about anything you need with regard to multithreading.
For example, running code on the UI-Thread:
Handler mUIHandler = new Handler(Looper.getMainLooper());
mUIHandler.post(new Runnable() {
/* Do something on UI-Thread */
});
Doing work on a background thread:
// This thread still needs to be explicitly started somewhere
HandlerThread mBackgroundThread = new HandlerThread("ThreadName");
// Sometimes you still need to think about some synchronization before calling getLooper()
Handler mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
// Execute code on the background thread the same way you would on the UI-Thread
Repeating a specific task after a given interval:
Runnable mTask = new Runnable() {
// Run this task (every 1000 ms) on the thread associated with mHandler
mHandler.postDelayed(this, 1000);
/* Perform the Task */
// You can also do this at the end if you wanted it to repeat 1000 ms AFTER
// this task finishes.
}

Can I do network operations (UI blocking) inside handlers/runnables?

in my mainActivity, which is the sole activity of my application, I am creating the below handler and running a runnable inside it.
I have some misunderstandings about handlers and where they run.
See the code
Handler handler;
#Override
protected void onCreate(Bundle bundle)
{
handler = new Handler();
handler.postDelayed(r , 5000);
}
Runnable r = new Runnable()
{
#Override
public void run() {
FetchServerAndUpdateStatus(); //network stuff in here
handler.postDelayed(r , 5000);
}
}
I assume this code will still run in UI thread and I won't be able to make any network calls in there no ?
If yes, what shall I do ? Create and use a seperate thread ?
If I created a new thread, How can I run the postdelayed method ? The thread does not have post delayed ?
Does not using handler/runnable and using TimerTask and Runnable instead a better approach ? Or, just like the above handler/runnable, that will also run on the UI thread, unless created inside a seperate one.
When you construct a Handler it is bound to the thread it is constructed on.
onCreate() is run on the UI thread so this handler will be bound to the Looper on the main thread, and thus will run on that thread.
If you want a handler you can use on another thread you can construct one.
See the looper docs: https://developer.android.com/reference/android/os/Looper.html
Which has this block:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
synchronized (this) {
this.notifyAll();
}
Looper.loop();
}
}
Add this class and then in your onCreate do the following:
mLooperThread = new LooperThread();
mLooperThread.start();
synchronized (mLooperThread) {
while (null == mLooperThread.mHandler) {
mLooperThread.wait();
}
}
mLooperThread.mHandler.postDelayed(r , 5000);
This will cause the runnable to be run NOT on the UI thread, which is probably what you wanted.
For tasks that need to interact with the UI an AsyncTask may be better since it includes a mechanism to run things that touch Views when the task is done on the UI thread, since anything that touches a View must be done on the UI thread.
The other mechanisms for executing on the UI thread are to post to the view itself:
https://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable)
or
[https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable, long)](https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable, long))
Or to ask the Activity to run it on the UI for you:
https://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
It depends on what you do with your handler, you didn't show, how you want to obtain m_handler. If you create it with new Handler(Looper.getMainLooper()), it will run on UI thread.
If you want to run code in background (network operations) you should use AsyncTask

Handler instead of Timer?

Basically this is what I am doing, instead of using a Timer I am using a Handler:
Handler h = new Handler();
Runnable r = new Runnable(){
public void run(){
//do something and schedule it again
h.postDelayed(r, 10000);
}
};
And I say h.removeCallBacks(r); when I want to stop it. Is it bad?
Is it bad.?
It's not bad, but that method just removes pending posts of Runnable.
Is it bad.?
No(unless you have some problems:)).
Don't forget to cancel that Runnable in the onPause method so you cancel any pending Runnable from running on a possible dead activity.
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.

java thread reusage via executor

I am confused on the following:
To use threads in a Java program, the simplest way is to extend Thread class and implement the runnable interface (or simply implement runnable).
To start the thread's execution. we must call the Thread's method start(), which in turn calls method run() of the thread. And so the thread starts.
The method start() (unless I am wrong) must be called exactly and only once for each thread. As a result, thread instances can not be reused unless somehow the run method itself runs in some-short of infinite loop that facilitates a custom implementation of the thread's reusage.
Now the javadoc
link text
says
Calls to execute will reuse previously constructed threads if available
I do not understand how this is implemented.
I provide in the execute method of the executor method my custom thread e.g.
ExecutorService myCachedPool = Executors.newCachedThreadPool();
myCachedPool.execute(new Runnable(){public void run(){
//do something time consuming
}});
How can this custom thread I delegeate to the executor framework be reused?
Is Executor is allowed to call method start() more than 1 time, while we can not in our programs?
Am I misunderstanding something?
Thank you.
Note that it's not Executor that calls start() - it's ExecutorService. And no, it's not calling start() twice. It doesn't start the task that you give it directly using Thread.start()... instead, it starts a thread which knows about that thread pool's queue of work. The thread will basically wait until there's some work to do, then pick it up and execute it, before going back to waiting. So although the thread performs several tasks, Thread.start() is only called once.
EDIT: Judging by the comments, you're a bit confused about the difference between a Runnable (which is a task to be executed) and a Thread (which is what executes tasks).
The same thread can execute multiple tasks. For a very simple example not using a thread pool, consider this:
public class MultiRunnable implements Runnable
{
private final List<Runnable> runnables;
public MultiRunnable(List<Runnable> runnables)
{
this.runnables = runnables;
}
public void run()
{
for (Runnable runnable : runnables)
{
runnable.run();
}
}
}
(Ignore the potential thread safety issues of using a List<T> from multiple threads.)
You could create a whole bunch of Runnable tasks capable of doing different things, then create a single MultiRunnable to run them in turn. Pass that instance of MultiRunnable into the Thread constructor, and then when you start the thread, it will execute each of the original runnable tasks. Does that help?
It is not calling start() more than once; instead the Thread in the pool never completes, but just stays alive---waiting. The source code is available for download if you want to look at it.
Each Thread in the thread pool can simply wait() for the Executor to hand it a new Runnable, but the Thread's own run() method has not completed. It simply waits for a new Runnable to be given to the Executor.
To "start" a thread more than once, create a runnable. For example:
//NO
private class T extends Thread { //not necessary to implement runnable
public void run(){
//...
}
}
void someMethod(){
T a = new T();
a.start();
a.start(); //NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO NO
}
Instead,
//Yes
private class T implements Runnable {
public void run(){
//...
}
}
void someMethod(){
T a = new T();
new Thread(a).start();
new Thread(a).start(); //YES YES YES
}
It is also possible to do this:
void someMethod(){
final Runnable r = new Runnable(){
public void run(){
//...
}
};
new Thread(r).start();
new Thread(r).start();
}
// r could also be a field of you class.

Categories