I want stop main thread, while alertDialog is open, and wait user's choice for continue the program (depending on the button pressed buttons (positive or negative)). When trying to stop thread after. show (); dialog is not draw; if hang listener's onDestract onClose it works, but the code is horrible.
You can't stop "main" thread, since it's gui thread - your alertDialog will become irresponsive. You need to use callback to perform desired operations.
Why you need to stop main thread? Is this some game?
You must use many thread, and never block main thread. For example, thread for logic, thread for draw.
If you need to stop drawing, simple set your noDraw=true property:)
Like this:
SomeDrawer extends View {
#override
public void onDraw(...){
if(noDraw) return;
redrawMyGame(...);
}
}
Related
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.
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.
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).
Well I just want to press a button and a countdown appears in it however when I press the button the program stops and finally shows the number 1 but doesn't show 3 or 2.
btnTurno.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
btnTurno.setText("3");
SystemClock.sleep(1000);
btnTurno.setText("2");
SystemClock.sleep(1000);
btnTurno.setText("1");
}
});
What I'm doing wrong?
First of all, Sleep should be called as Thread.sleep(x);
But on the other hand , sleep is NOT recommended since it will block the user interaction with the application.
If you want to make a countdown ( as it looks like what you are doing ), you should look at this
http://developer.android.com/reference/android/os/CountDownTimer.html
onClick is being executed in single handler message on GUI thread, so each time you change text, it overwrites previous value, so system is not able to redraw view.
Also you should not call sleep() on main gui thread, that will cause ANR - application is notresponding
Setting the text and drawing the text are separate operations that both happen on the same thread. You're setting the text three times before the framework gets the chance to draw anything, so all you see is the last change.
For this to work, you'd need to do your text updates and sleeps on a separate thread. However, you can't make UI calls directly on a different thread, so you need to post your messages.
One approach would be to create an AsyncTask, and use your code above but call publishProgress() where you're currently calling setText(). The publishProgress() call in the async thread results in onProgressUpdate() running in the UI thread; from there, you can call setText() to update the UI.
Edit: the CountDownTimer approach mentioned in a different answer is better.
I am creating an AlertDialog using an AlertDialog.Builder and showing it. After showing it, I need to pause application until the user comfirms the Dialog.
I exactly need to pause in a method showing Dialog thread, because its calling method throws a fatal error after return.
Is there any way to do that?
In Android, you can't pause the UI-Thread, as it will result in the OS showing the Application is not responding dialog after about 5 seconds of being paused.
Also, as mentioned by CommonsWare in the comments, Dialogs don't operate in a separate thread.
Without seeing your code it's a bit difficult to answer, but what I could suggest right now is place all the code you need to "pause" in an AsyncTask.
You can place all the code before the pause in the onPreExecute() method, than show your dialog, and in the doInBackground() method, maybe in a while loop or something with volatile variables or something (this code runs on a background thread so it won't stuck the UI-Thread) and then the code after the pause in the onPostExecute() method.
both onPreExecute() and onPostExecute() operates on the UI-Thread. the onPost is called after the doInBackground has finished.
But again, if you'd show some code of the pause it would be easier to help you.
Further reading: AsyncTask
Another way to handle this is to use threads. In a non-UI thread, call your AlertDialog's show() method using the runOnUiThread() method of your Activity. Call Object.wait() in your non-UI thread, and call Object.notifyAll() in your AlertDialog's OnClickListener. The non-UI thread will then wait until the user clicks on your AlertDialog.
I tried to look clear answer for it but wasn't able to find it anywhere. I am running background thread in main activity that checks for certain variable and if it is true it should show alert dialog. I also want this dialog to show up on any focused activity of the application. I tried it by adding Looper.prepare() and Looper.loop() to the thread but it does not work properly and it affects while() loop that I use to check variable in that thread. Can anyone please help me in finding out what is the best way to implement this?
Thanks.
If you construct the background thread using the main/ui thread, you can create a Handler in the constructor. When you want to run some code on the main/ui thread, you simply Handler.post(Runnable r) with a runnable to the ui thread.
If your background thread is not being constructed on the ui/main thread, you can use a BroadcastIntent to and a BroadcastReceiver pattern to send messages between your background thread and your foreground activities. This is especially useful if you are switching foreground activities during the useful life of your background thread.
You may want to try creating an implementation of Runnable and passing that to a View's post() method.
final Runnable r = new Runnable() {
public void run() {
//code to display dialog
}
}
final View view = findViewById(R.id.XYZ);
view.post(r);
This will run the Runnable on the UI thread.
Ok, i can see two approaches. The first one is a dirty but quick:
You can extend TimerTask and Handler classes. YourTimerTask will check variable and send a Message to YourHandler. YourHandler should override handleMessage and show a dialog.
The second one might be an overkill, but still. Android is event-based. It means that system gives you an opportunity to create your own events and handle it. So, you can start a Service, which will check your variable and send a Broadcast (can be local). In your activity you have to create your own BroadcastReceiver and register it. This receiver will handle a message.
I am developing my first Androïd application and I'm facing a problem when I want to display a ProgressDialog to indicate that a process is being run.
In my application, the user triggers a time consuming task by pressing a Button. The "OnClick" function of my "OnClickListener" is called when the user presses the Button. In this function, here is what I'm currently doing :
- creation and configuration of an instance of the ProgressDialog class,
- creation of a thread dedicated to the time consuming task,
- attempt to display the ProgressDialog using the "show" method,
- start of the thread,
- main Activity suspended (call of the "wait" function)
- wake up of the main Activity by the thread when it is finished
- removal of the ProgressDialog by calling the "dismiss" function.
Everything works fine (the result of the long task is correct) but the ProgressDialog nevers appears. What am I doing wrong?
Thanks in advance for the time you will spend trying to help me.
You should not call wait() to the Main Activity/UI thread, because this is actually freezing the UI including your ProgressDialog, so it has no time to fade in and will never be shown.
Try to use multithreading correctly: http://developer.android.com/resources/articles/painless-threading.html
final Handler transThreadHandler = new Handler();
public void onClick(View v) {
// show ProgressDialog...
new Thread(){
public void run(){
// your second thread
doLargeStuffHere();
transThreadHandler.post(new Runnable(){public void run(){
// back in UI thread
// close ProgressDialog...
}});
}
}.start();
}
I would suggest using AsyncTask, as it's purpose is exactly to handle this kind of problem. See here for instructions how to use it. Note that the linked page in Floern's answer also recommends the use of AsyncTask.
You would need to do the following:
subclass AsyncTask
override it's onPreExecute() method to create and show a ProgressDialog. (You could hold a reference to it in a member of your subclass)
override it's doInBackground() method to execute your time consuming action.
override it's onPostExecute() method to hide your dialog.
in your activity, create an instance of your subclass and call execute() on it.
If you make your subclass an inner class of your activity, you can even use all of your activity's members.