Why is Thread.sleep() not pausing my code? [duplicate] - java

For my new Android application I need a function, that timeout my application for 3 Seconds. I tried the function "sleep()" like this:
seekBar1.setProgress(50); // Set something for my SeekBar
try{
Thread.sleep(3000); // Wait for 3 Seconds
} catch (Exception e){
System.out.println("Error: "+e); // Catch the exception
}
button.setEnabled(true); // Enable my button
It seems to work, but if I was running the application it does it like this: Wait for 3 Seconds, set progress and enable button. I want first to set the progress and then wait for 3 seconds and only then to enable the button.
Is "sleep()" for the right for my use or what can I do else that my application does it in the right order?

You can use postDelayed() method like this:
handler=new Handler();
Runnable r=new Runnable() {
public void run() {
//what ever you do here will be done after 3 seconds delay.
}
};
handler.postDelayed(r, 3000);

You shouldn't ever block the ui thread with a sleep. Its ok to sleep on another thread, but even then it should be avoided. The right way to do this is to post a Runnable to a Handler. Then put whatever code you want to run after the delay in the run() method of the Runnable.

You can define a Handle in your Activity and use Handle.postDelayed() from Activity's onCreate()so you receive a message on that handle in 3 seconds. Upon receving you can enable the button.
You can do the same using AsyncTask where in doInBackground() you just sleep for 3 sec. Then in onPostExecute() you enable the button.

Use object of Handler class and use method handler.postDelayed(thread,time).Don't use sleep() it will block ui thread.

Related

How does Platform.runLater() function?

I have a simple app which updates the data in the background and while it updates, it disables all the other buttons and enables a TextArea to show the progress.
Steps:
Disable all the other buttons in the mainUI (Button name: plotButton)
Enable a TextArea showing that the updating has started (TextArea name: infoLogTextArea)
Then only start the update method (update() throws Exceptions).
Here is the code:
#FXML
public void handleUpdateButton() {
infoLogTextArea.setVisible(true);
infoLogTextArea.appendText("Please wait while downloading data from internet.....\n");
plotButton.setDisable(true);
updateButton.setDisable(true);
if(c!=null) {
Runnable task = new Runnable() {
#Override
public void run() {
// Thread.sleep(10000); -> sleep for 10secs
Platform.runLater(new Runnable() {
#Override
public void run() {
try {
c.updateData();
infoLogTextArea.appendText(c.getErrorLog().toString());
plotLabel.setText(c.getCityData().size()+" cities found and updated from internet");
infoLogTextArea.appendText("Successfully updated the data from Internet\n");
}catch (IOException e) {
infoLogTextArea.setText("Couldnot update the data from web: "+e.getMessage()+"\n");
}
finally {
plotButton.setDisable(false);
updateButton.setDisable(false);
}
}
});
}
};
new Thread(task).start();
}else {
System.out.println("c not initialized");
}
}
Now the code works well but sometimes steps 1 and 2 are not executed and it starts step 3 (updating) which can freeze the program.
If I put Thread.sleep(10 secs) in between step 2 and 3 then it works completely fine. (it is commented in the code)
But can anybody explain what is going on behind the scenes and why Platform.runLater() doesn't work all the time?
A JavaFX application runs on the Application thread, which handles all the UI elements. This means that if you click Button A and clicking that button starts method A that takes 5 seconds to complete, and then one second after clicking that button, you try to click Button B which starts method B, method B won't start until method A finishes. Or possibly Button B won't even work until method A finishes, I'm a little fuzzy on the detail there.
A good way to stop your application from freezing is to use Threads. To fix the above scenario, clicking Button A will start method A that starts a new Thread. Then the Thread can take as long as it wants to complete without locking up the UI and preventing you from clicking Button B.
Now, say something in method A needed to be on the application thread, for example, it updated a UI component, like a Label or a TextField. Then inside your Thread in Method A you would need to put the part that affects the UI into a Platform.runLater(), so that it will run on the Application Thread with the rest of the UI.
What this means for your example is that you have two options.
1. Don't use threads at all, since you don't want the user to be interacting with the UI while the updates are happening anyway.
2. move c.updateData() out of the Platform.runLater() like this:
Runnable task = new Runnable() {
#Override
public void run() {
c.updateData();
Platform.runLater(new Runnable() {
#Override
public void run() {
try {
infoLogTextArea.appendText(c.getErrorLog().toString());
plotLabel.setText(c.getCityData().size()+" cities found and updated from internet");
infoLogTextArea.appendText("Successfully updated the data from Internet\n");
}catch (IOException e) {
infoLogTextArea.setText("Couldnot update the data from web: "+e.getMessage()+"\n");
}
finally {
plotButton.setDisable(false);
updateButton.setDisable(false);
}
}
});
}
};
Either one of those will work, but what you're doing right now is you're on the application thread, and then you start another thread whose only purpose is to run something on the application thread.
The documentation of the Platform class explain everything very well :
public static void runLater(Runnable runnable)
Run the specified Runnable on the JavaFX Application Thread at some
unspecified time in the future. This method, which may be called from
any thread, will post the Runnable to an event queue and then return
immediately to the caller. The Runnables are executed in the order
they are posted. A runnable passed into the runLater method will be
executed before any Runnable passed into a subsequent call to
runLater. If this method is called after the JavaFX runtime has been
shutdown, the call will be ignored: the Runnable will not be executed
and no exception will be thrown. NOTE: applications should avoid
flooding JavaFX with too many pending Runnables. Otherwise, the
application may become unresponsive. Applications are encouraged to
batch up multiple operations into fewer runLater calls. Additionally,
long-running operations should be done on a background thread where
possible, freeing up the JavaFX Application Thread for GUI operations.
This method must not be called before the FX runtime has been
initialized. For standard JavaFX applications that extend Application,
and use either the Java launcher or one of the launch methods in the
Application class to launch the application, the FX runtime is
initialized by the launcher before the Application class is loaded.
So use the runLater to only update any UI elements on a non JavaFX thread and leave any heavy job to sit on the background thread.

Calling thread repeatedly causing Ui hang in android

I am developing a Bluetooth application.In that I have 1 button, on click of the button I am starting a thread.Inside the thread, I am discovering and connecting ble devices.Repeated click of the button causing the UI to hang.
Code I am using to create the thread is:
new Thread(new Runnable() {
#Override
public void run() {
//do bluetooth stuffs
}
}).start();
I am not stopping this thread anywhere.
I don't know what is causing the UI to hang please help me.
Do you mean that if you keep smashing the button repeatedly (without waiting for the task to finish), then the ui lags? Or when you press the button, wait a bit, then press again.
If it's the first case (where you're mashing the button in quick succession), try this: If you set some boolean flag when you first start the process, then each time you press the button check if that flag is set to true, and only execute the search if the flag is false. Not sure if this is your issue but it's worth a shot?
For the Android, you can use handler instead thread or handle your thread using handler is a better way, for example, you can use like
new Handler().post(new Runnable() {
#Override
public void run() {
}
});
if you want to use the main thread then use like.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
}
});
for information, you can refer this link
difference between Thread and Handler
I would advise you to use a thread pool instead. Resources are limited.I didn't understand why are you creating a new thread for every button press. a bunch of threads banging for a resource might freeze Your app, or there could be implementation related issues like a deadlock, thread contention, or thread starvation which will definately prompts to freeze your application.

Is the Thread really stop when I use new Thread().interrupt();?

I create a Thread like the following code. This Thread will send the POST request.(The code is not yet written , so I didn't post the detail code of Thread )
final Runnable Update_Value = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
**// It will send the POST request to the Server**
}
};
I use the new Thread(Update_Value).start(); to run the Thread.
And I use new Thread(Update_Value).interrupt(); to interrupt the Thread.
1. If I use new Thread(Update_Value).start(); to run the Thread.
2 How to interrupt the Thread when I using new Thread(Update_Value).start(); ?
3 Is the thread close when App close if I didn't close it ?
Sorry about my English...Thanks in advance.
If you use new Thread each time, the two calls create two different threads; they don't act on the same thread.
The interrupt() method does not stop the thread. Rather, it tells the thread to take a look at any interrupt flags that may also have been set, such as a shutdown flag. The thread itself must contain code to check for interrupts and to check for flags such as shutdown flags.
interrupt method is used to send an interrupt signal to a running thread. Calling on a new thread does not make sense.
To properly handle the interrupt signal, your thread code should catch InterruptedException. Something like this:
try {
// do thread task
} catch (InterruptedException e) {
// interrupted: if required do something on interrupt or simply return
return;
}

Stopping the Timer's Running in Application, if Internet Connectivity is Lost

Most of the times we as programmers experience this problem, when we are in between of certain Asynctask doinBackground() Method - performing an operation which requires Network (Internet Connection), and if in between the network is lost then our Application results in Force Close or Crash, or FreeZed. To stop this we use try/catch operations to be used with the code.
I just want to know is there any perfect means to do the same, Scenario written below,
Here in my case:
I require Internet Connection after every 20secs to parse an API in the Asyntask, and based upon the result of the API, I have to update the UI on the screen.
Here is my Timer Method
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
if(DCCStaticMethod.checkInternet(DriverMainMenuActivity.this)){
try {
if(mLocalAreaDriverPass.getStatus() == AsyncTask.Status.FINISHED){
mLocalAreaDriverPass = new LocalAreaDriverPass(DriverMainMenuActivity.this,true);
mLocalAreaDriverPass.execute();
Log.d("RefreshLocalAreaTimerDriver", "running");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};
timer.scheduleAtFixedRate(task, 20000, 20000);
Suppose at any instant of time, the internet connectivity is lost or goes down, how to cancel and restart the timer again to achieve my requirement.
I HAVE SO MANY TRICKS AND CRANKS TO PERFORM THE SAME, BUT I AM IN SEARCH OF GOOD MEANS TO PERFORM THESE TYPES OF TASKS IN FUTURE, AS THESE TYPES OF TASKS OCCUR IN ALMOST ALL THE APPS
In Catch block first cancel the Timer and register a broadcast for Network Connection. In broadcast receiver start your timer again.Here are the docs for monitoring Network.
Make broadcast receiver for checking internet connection. and get status of that. if connection is lost then set value to variable of any application class or simple class and then use that variable in activity for stop timer.
There is a custom class CountdownTimerwithPause.By using this you can pause and cancel the timer in middle of Asyn Task
Refer the below link
How to extend CountDown Timer With Pause?

Is there any way to stop background thread without process kill in Android?

My application has one service which runs until user pressed exit button. I know giving exit button in android is not good design but in my application it is desired.
In my application I also have a thread to send Http request, download a file and then parse it in background so that UI will not block. In my thread's run method there are sequential steps (like download a file, then parse it), there is no while or for loop in it.
When user presses exit button, is there any way to stop the background thread if it is running without kill process (using Process.kiil(pid) or System.exit(0)) ?
I have tried AsyncTask also. Whatever in run method of thread, i put it in doInBackground method. When user presses exit button i have canceled asynctask. Cancelling task not stop the background thread completely because after file download it will go in parser to parse the file (i.e. parsing is done in background thread but it at the time of parsing it is not in doInBackground or run method. It will in parsing method of parser class or in Default handler class for parsing.)
From googling I read many blogs and other stackoverflow questions about thread but still I cannot find any solution for it.
Please help....thanks in advance..
before each step you could add a line like
if(stillRunning){
//next step
}
and when you want it to stop, you just set stillRunning to false.
(1) use this to stop application instead of exit
finish();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
(2) use new Thread instead of asynk task which you can stop by calling stop method
Thread myThread = new Thread ()
{
public void run()
{
Looper.prepare();
doMyWork();
}
}.start();
and call stop on myThread
Probably, your connection and parser use same InputStream. If you quit, try to close the stream and a connection. In that case, some kind of Exception will be thrown and background thread will finish job with error but very fast. If you are in the middle of file saving, you must check every write(buffer) if you are canceled or try to close FileOutputStream.
Stop thread at instance (when exit event occurred from UI) is not possible without using
Process.killProcess(Process.myPid());

Categories