Reputation: 186
I'm creating an android application and i want when user press back button show an quick animation and then finish current activity.
I'm using following code for do this:
public void onBackPressed() {
Thread t = new Thread(){
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
animate();
}
});
}
};
t.start();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
this.finish();
}
But it doesn't work.
Upvotes: 0
Views: 821
Reputation: 93678
Don't use join. Using join pauses the main thread until it is finished. But you can't redraw until the main thread returns to the Looper and processes invalidate events. So the entire thing won't work- your code is basically doing the same thing as if you hadn't run a thread at all.
Never wait on the UI thread- that means not only sleep but also join. Instead, when the animation is finished you call finish then, and just return after you call thread.start. But all of this is extremely overly complicated, for what you're doing just post a message to a Handler.
Upvotes: 2
Reputation: 1007349
I'm creating an android application and i want when user press back button show an quick animation and then finish current activity.
Personally, I do not recommend this. Think of it this way: when you press the BACK button in a desktop Web browser, how angry would you be if the Web site decided to display an ad before taking you back to the preceding page?
But it doesn't work.
onBackPressed()
is called on the main application thread. You then create and start()
a background thread. You then immediately call join()
, to block the main application thread until the background thread ends.
This has two problems:
The background thread is pointless, as you are blocking the main application thread until that background thread is done.
runOnUiThread()
takes your Runnable
and arranges to run it on the main application thread. That cannot happen immediately, because you are blocking the main application thread.
Your code has the same effect as this:
public void onBackPressed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
animate();
}
});
this.finish();
}
As a result, animate()
will not be called until after the activity has finished.
A typical solution is to attach a listener to the animation, to be invoked when the animation is complete. Then, the listener can call finish()
. Another solution is to schedule a Runnable
, using postDelayed()
on some View
, to be invoked after a certain amount of time, using a value that matches your expected animation run time. Then, the Runnable
you pass to postDelayed()
could call finish()
.
But, again, I do not recommend interfering with BACK button processing. I do not know what the user experience will be like on an Android 7.0+ multi-window environment (e.g., Chrome OS devices, Samsung DeX).
Upvotes: 1