after onPause() method stop "active" handler - java

calling the method handler.removeMessagesAndCallbacks(null) stops all handlers which are not executed yet (post delayed). but i need a method i can't find which interrupts the handler already running.
a thread can be interrupted while being executed. can a handler also be interrupted like a thread?
here an example:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
> ...
}, 0);
handler.postDelayed(new Runnable() {
> ...
}, 1000);
#Override
protected void onPause() {
> super.onPause();
> handler.removeMessagesAndCallbacks(null);
}
the post delayed handler of 1000 is canceled, but the other handler is still being executed when calling onPause(), when already running.
Can i cancel a handler already being executed? Is there an easier opportunity than Override the Runnable or Handler class? If not, can somebody tell me how to Override, only for the case to cancel the runnable in the handler?
In my case the handlers are executing post delayed animations. I cannot cancel every single animation programatically. the runnable (handler) should be canceled including the animations should be canceled too. Thank you!

I think a good practice for what you want is using kotlin coroutines.
by using coroutines you can define some jobs that can be executed in the main thread or background threads. but the good point about them is that you can cancel them at any time you want by using job.cancel().
and if you want to do this with runnable and java maybe this question can help you:
Android: How do I stop Runnable?

Related

Delay a method in UI thread without blocking it [duplicate]

I want to update my UI from a Thread which updates a Progressbar. Unfortunately, when updating the progressbar's drawable from the "runnable" the progressbar disappears!
Changing the progressbars's drawable in onCreate() on the otherside works!
Any Suggestions?
public void onCreate(Bundle savedInstanceState) {
res = getResources();
super.onCreate(savedInstanceState);
setContentView(R.layout.gameone);
pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); //**Works**/
handler.postDelayed(runnable, 1);
}
private Runnable runnable = new Runnable() {
public void run() {
runOnUiThread(new Runnable() {
public void run()
{
//* The Complete ProgressBar does not appear**/
pB.setProgressDrawable(getResources().getDrawable(R.drawable.green));
}
});
}
}
You should do this with the help of AsyncTask (an intelligent backround thread) and ProgressDialog
AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called begin, doInBackground, processProgress and end.
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
onPreExecute(), invoked on the UI thread immediately after 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. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. 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...). The timing of the execution is undefined. This method is used to display any form of progress in the user interface while the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
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.
Threading rules
There are a few threading rules that must be followed for this class to work properly:
The task instance must be created on the UI thread.
execute(Params...) must be invoked on the UI thread.
Do not call onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...) manually.
The task can be executed only once (an exception will be thrown if a second execution is attempted.)
Example code
What the adapter does in this example is not important, more important to understand that you need to use AsyncTask to display a dialog for the progress.
private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected ContactsListCursorAdapter doInBackground(Void... params) {
cur1 = objItem.getContacts();
startManagingCursor(cur1);
adapter1 = new ContactsListCursorAdapter (viewContacts.this,
R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});
return adapter1;
}
protected void onPostExecute(ContactsListCursorAdapter result) {
list.setAdapter(result);
dialog.dismiss();
}
}
The most simplest solution I have seen to supply a short
execution to the UI thread is via the post() method of a view.
This is needed since UI methods are not re-entrant. The
method for this is:
package android.view;
public class View;
public boolean post(Runnable action);
The post() method corresponds to the SwingUtilities.invokeLater().
Unfortunately I didn't find something simple that corresponds to
the SwingUtilities.invokeAndWait(), but one can build the later
based on the former with a monitor and a flag.
So what you save by this is creating a handler. You simply need
to find your view and then post on it. You can find your view via
findViewById() if you tend to work with id-ed resources. The resulting
code is very simple:
/* inside your non-UI thread */
view.post(new Runnable() {
public void run() {
/* the desired UI update */
}
});
}
Note: Compared to SwingUtilities.invokeLater() the method
View.post() does return a boolean, indicating whether the
view has an associated event queue. Since I used the
invokeLater() resp. post() anyway only for fire and forget,
I did not check the result value. Basically you should
call post() only after onAttachedToWindow() has been called
on the view.
Best Regards
If you use Handler (I see you do and hopefully you created its instance on the UI thread), then don't use runOnUiThread() inside of your runnable. runOnUiThread() is used when you do smth from a non-UI thread, however Handler will already execute your runnable on UI thread.
Try to do smth like this:
private Handler mHandler = new Handler();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gameone);
res = getResources();
// pB.setProgressDrawable(getResources().getDrawable(R.drawable.green)); **//Works**
mHandler.postDelayed(runnable, 1);
}
private Runnable runnable = new Runnable() {
public void run() {
pB.setProgressDrawable(getResources().getDrawable(R.drawable.green));
pB.invalidate(); // maybe this will even not needed - try to comment out
}
};
Use the AsyncTask class (instead of Runnable). It has a method called onProgressUpdate which can affect the UI (it's invoked in the UI thread).
You need to create a Handler in the UI thread and then use it to post or send a message from your other thread to update the UI
If you don't like the AsyncTask you could use the observer pattern. In that example use the ResponseHandler as an inner class in your activity then have a string message that will set the progress bars percentage... You would need to make sure that any alterations to the UI are performed within the ResponseHandler to avoid freezing up the UI, then your worker thread (EventSource in the example) can perform the tasks required.
I would use the AsyncTask tho, however the observer pattern can be good for customization reasons, plus its easier to understand. Also im not sure if this way is widely accepted or will 100% work. Im downloading and the android plugin now to test it
As recommended by official documentation, you can use AsyncTask to handle work items shorter than 5ms in duration. If your task take more time, lookout for other alternatives.
HandlerThread is one alternative to Thread or AsyncTask. If you need to update UI from HandlerThread, post a message on UI Thread Looper and UI Thread Handler can handle UI updates.
Example code:
Android: Toast in a thread

How does an animation work on UI thread without blocking other messages and runnable in message queue of UI Thread?

I am working on some old android code where the code looks something like this:
public void TestMethod() {
// handler posting on main thread
handler.post(() -> {
//Invokes method();
});
animation.addListener(new AnimatatorListenerAdapter(){
#Override
public void onAnimationEnd() {
// Do some stuff;
}
});
animation.start();
}
As per my understanding, the animation life cycle callbacks always execute on UI thread. Since method() is posted first on message queue therefore it should be executed before onAnimationEnd(), but some times (3/10 times) onAnimationEnd executes before method(). Therefore now I am confused about android animation ( Surely I am missing something).
Questions:
What should be the ideal flow in this code?
Between method() and onAnimationEnd(), which one will be executed first and why?
How android animation executes on UI thread without blocking other messages and runnable in the message queue of UI Thread?

Which thread does Runnable run on?

I want to update UI every 100ms. After searching in StackOverflow, I found a solution using Runnable and Handler like this
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
//update UI here
handler.postDelayed(this, 100);
}
};
runnable.run();
It works! But I have some questions:
Which thread does this Runnable run on? MainThread or another thread? Here is the docs about postDelay
Handler is attached MainThread, so is Runnable running on MainThread?
If Runnable is running on MainThread, why needs Handler? According to my knowledge, Handler is used to send messages between two threads
Which thread does this Runnable run on?
Runnable runnable = new Runnable() {
#Override
public void run() {
//update UI here
handler.postDelayed(this, 100);
}
};
runnable.run()
This Runnable runs on the current thread, i.e. the thread that invokes this code. It doesn't magically create, or constitute, another thread. Runnable.run() is only a method call.
The subsequent executions of this thread, by the Handler, in whatever thread the Handler runs in, do essentially nothing except reschedule themselves. It's hard to believe this is a solution to anything.
In your example, the Runnable runs on the UI Thread.
If you want your Handler and all its Runnable to run in a different Thread, you'll have to assign it a a new HandlerThread's Looper.
final HandlerThread handlerThread = new HandlerThread(MY_THREAD_ID);
handlerThread.start();
final Handler handler = new Handler(handlerThread.getLooper());
You can then pass the Runnable instance via postDelayed(Runnable, long).
Runnable r = new Runnable() {
#Override public void run() {
handler.postDelayed(this, 2000);
}
};
handler.postDelayed(r, 0);
Handler is attached MainThread, so is Runnable running on MainThread?
From Handler documentation:
Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.
If you want to run your Runnable on different Thread, you can use HandlerThread .
Related post:
Why use HandlerThread in Android
If Runnable is running on MainThread, why needs Handler? According to my knowledge, Handler is used to send messages between two threads
There are two main uses for a Handler:
To schedule messages and runnables to be executed as some point in the future
To enqueue an action to be performed on a different thread than your own.
If you are using only MainThread,Handler is useful to send message at some point of time in future. If you are using different Threads, Handler is useful to communicate between the threads.

What is the best way to wait until a runnable on the main thread completes in Android?

I need to collect a username and password from a user inside WebViewClient#shouldInterceptRequest, so I must block the WebView IO thread until the user supplies a username and password on the main thread. What is the best way to wait until my runnable completes?
My current favorite way is (exceptions and timeouts omitted for brevity):
final CountDownLatch countDownLatch = new CountDownLatch(1);
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
callSomethingWithAsyncCallback(new Runnable() {
public void run() {
countDownLatch.countDown();
}
});
}
});
countDownLatch.await();
Something that uses ExecutorServices seems better since I can simply use Future#get to block. However, there is no ExecutorService that runs on the main thread, and using one from Executors just to bounce it to the main thread seems wasteful. Thoughts?
Please use AsyncTask rather than using runnable.
The AsyncTask executes everything in doInBackground() inside of another thread, which does not have access to the GUI where your views are.
preExecute() and postExecute() offer you access to GUI before and after the heavy lifting occurs in this new thread, you can even pass the result of the long operation to postExecute() to then show any results of processing.

Stopping a Timer Task from within a Runnable thread when shutdown

I have a TimerTask that gets started as the first thing in my run() method of my Runnable class. I want to make sure that it gets stopped when the runnable is shutdown.
The runnable is started via an ExecutorService. I don't see a way to get a hook back to the runnable from the ExecutorService when shutdown() is called.
How can I make sure that the TimerTask is stopped?
Thanks
use ExecuterService.submit() to get back Future object once the task is completed.
ExecutorService.Submit()
The method call TimerTask.cancel() should do the desired.
Your Runnable.run method could be designed like this:
public void run() {
pingTask = new PingTimerTask(...);
try {
...
} finally {
/* this code even gets executed when an exception
* (for example an *InterruptedException*) was thrown:
*/
pingTask.cancel();
}
}

Categories

Resources