(Android) How can I make a loop waiting a short time (like half an sec.) before doing another loop?
void replaceText(String s)
{
doSomething1();
int x = 0;
while (x < 5)
{
doSomething2();
x++;
}
doSomething3();
}
So what I want is that my app "waits" a short time after the method doSomething2(). Google could't help me this time:D
You can try using a Handler
// Execute some code after 1 second have passed
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
doSomething2();
}
}, 1000);
if you want your while loop to be executed every 1000ms for example, you can do this:
final Handler handler=new Handler();
Runnable r=new Runnable() {
public void run() {
doSomething2();
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
This will execute doSomething2() every 1000ms.
Specific to your example, you can try the following option as well:
void replaceText(String s)
{
doSomething1();
int x = 0;
while (x < 5)
{
Thread.sleep(100);
doSomething2();
x++;
}
doSomething3();
}
Note that since Thread.sleep stops the thread, make sure you run this function on a non-UI thread. A naive implementation for this will be:
void replaceText(String s)
{
final String str = s;
Thread thread = new Thread() {
#Override
public void run() {
// user str instead of s;
doSomething1();
int x = 0;
while (x < 5)
{
Thread.sleep(100);
doSomething2();
x++;
}
doSomething3();
}
};
thread.start();
}
Thread.sleep(500);
Will cause your code to sleep for half a second before continuing. Note that you will then need to handle the InterruptedException appropriately.
Related
i'm trying to make a delay inside while loop using Thread.sleep() method . here is my code :
new Thread(new Runnable() {
#Override
public void run() {
z=0;
while (z<45){
z++;
handler.post(new Runnable() {
#Override
public void run() {
time.setText(Integer.toString(45-z));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
this code was working and suddenly a problem occurred . it started to make a delay less than one minute , sumtimes 500 ms and sumtimes less than that
Instead if using a different thread, Thread.sleep(), Handler and while loop you can try only with Handler like this,
private int timerCount = 0;
private static Handler myHandler = new Handler();
private void runVVRunnable() {
myHandler.postDelayed(runnable, 1000);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
timerCount++;
if ((time == null)) {
return;
}
if (timerCount <= 45) {
time.setText(Integer.toString(timerCount));
runVVRunnable();
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
myHandler.removeCallbacks(runnable);
}
you can just call runVVRunnable() it will do the same process which you are doing while loop
Just a guess but when sleeping/waiting on Java thread you need to try-catch InterruptedException.
This exception is thrown when "someone" calls interrupt() on your thread.
This will cause the thread to wake up from sleep early than expected.
Check if you catch InterruptedException before your thread terminated.
Is there any way of running a handler inside a loop?
I have this code but is not working as it does not wait for the loop but executes the code right way:
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
public void run() {
// need to do tasks on the UI thread
Log.d(TAG, "runn test");
//
for (int i = 1; i < 6; i++) {
handler.postDelayed(this, 5000);
}
}
};
// trigger first time
handler.postDelayed(runnable, 0);
Of course when I move the post delayed outside the loop works but it does not iterate nor execute the times I need:
final Handler handler = new Handler();
final Runnable runnable = new Runnable() {
public void run() {
// need to do tasks on the UI thread
Log.d(TAG, "runn test");
//
for (int i = 1; i < 6; i++) {
}
// works great! but it does not do what we need
handler.postDelayed(this, 5000);
}
};
// trigger first time
handler.postDelayed(runnable, 0);
SOLUTION FOUND:
I need to use asyntask along with Thread.sleep(5000) in the doInBackground method:
class ExecuteAsyncTask extends AsyncTask<Object, Void, String> {
//
protected String doInBackground(Object... task_idx) {
//
String param = (String) task_idx[0];
//
Log.d(TAG, "xxx - iter value started task idx: " + param);
// stop
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//
Log.d(TAG, "xxx - iter value done " + param);
return " done for task idx: " + param;
}
//
protected void onPostExecute(String result) {
Log.d(TAG, "xxx - task executed update ui controls: " + result);
}
}
for(int i = 0; i < 6; i ++){
//
new ExecuteAsyncTask().execute( String.valueOf(i) );
}
Instead of using a for loop, you can let the Runnable instance call itself for a specific number of times. These calls will be posted to UI thread queue so, keep that in mind. Also, since the delay is quite large, make sure the event is still needed when you trigger it next time.
The following code should do it:
final Handler handler = new Handler();
int count = 0;
final Runnable runnable = new Runnable() {
public void run() {
// need to do tasks on the UI thread
Log.d(TAG, "Run test count: " + count);
if (count++ < 5) {
handler.postDelayed(this, 5000);
}
}
};
// trigger first time
handler.post(runnable);
Here is a simple logic I made, without moving the for loop inside runnable.
for(int i = 1; i<=5; i++){
...
new Handler().postDelayed(() -> myFunctionToExecute() , i * 1000);
}
So whenever the loop iterates, it just extends the handler delay. And this way, you may achieve. I was searching for something similar, couldn't find anything, because in my case I already did the implementation of for loop, moving it inside the run() creates a mess
My solution to this problem if anyone has simmilar issues:
int count = 0;
public static void method(param1, param2, param3) {
Runnable r = () -> { //put method inside runnable
View view = listView.getChildAt(position); //action to be complete
if (view != null) { //if action is successfully complete
view.setSelected(true); //do something with this
} else { //do a looper
if (count < 10) { //limited looper to certain number
count++;
method(param1, param2, param3); //run the method again
}
};
Handler h = new Handler(); //create a new Handler and post above thread with it
h.postDelayed(r, 300);
}
Basically, I have created an if-else statement where else statement runs the same method with postDelayed() again for a limited number of trials.
This can be another solution
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int i;
public void run() {
for (i = 1; i < 6; i++) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
// need to do tasks on the UI thread
Log.d(TAG, "runn test");
}
}, 0);
//Add some downtime
SystemClock.sleep(5000);
}
}
};
new Thread(runnable).start();
I want to use the below mentioned operations in JAVA for android development.
For 30 Seconds ,Run a Function F1() every 1 second (resulting in 30 F1 calls).
Run a Thread t1 forever
The above steps should execute sequentially.
I Have tried with ExecutorServicebut with no success.
This is my code for reference
final Handler h = new Handler();
final int delay = 1000; //milliseconds
ExecutorService executor = Executors.newFixedThreadPool(1);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
F1();
}
});
for(int i=0;i<30;i++){
executor.submit(t1);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
//Step 2 (THe Second Thread)
h.postDelayed(new Runnable() {
public void run() {
AnotherFunction()
h.postDelayed(this, delay);
}
}, delay);
Generally, ExecutorService is more preferable for such operations. Here is a good post describing the differences and features of Timer and ExecutorService.
As for your question directly - it can be implemented in such way:
// here are Runnables with test logic
Runnable foo = new Runnable() {
#Override
public void run() {
Log.d(">>>", "foo");
onTaskFinished();
}
};
Runnable longRunning = new Runnable() {
#Override
public void run() {
try {
Log.d(">>>", "longRunning started");
Thread.sleep(5000);
Log.d(">>>", "longRunning finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// and here is valuable logic
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> schedulerHandler;
volatile AtomicInteger tasksNum = new AtomicInteger(0);
private synchronized void onTaskFinished(){
if(tasksNum.incrementAndGet() >= 30){
scheduler.execute(new Runnable() {
#Override
public void run() {
schedulerHandler.cancel(true);
}
});
scheduler.execute(longRunning);
}
}
And then to start operation just invoke this command:
schedulerHandler = scheduler.scheduleAtFixedRate(foo, 0, 1, TimeUnit.SECONDS);
You may consider using the java.util.Timer and java.util.TimerTask classes
If you're doing what I think you're doing you can do as #erosb hinted, use Timer and TimerTask to schedule method executions at a fixed rate.
The following should work for you.
final int DELAY_BEFORE_START = 0;
final int RATE = 1000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
F1();
}
}, DELAY_BEFORE_START, RATE);
I have the following code:
int x=0;
private void startTimerThread() {
System.out.println("enter");
System.out.println("percentage"+percentage);
System.out.println("x"+x);
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
for (x = 0; x>= percentage; x++ ) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable(){
public void run() {
textpercentage.animate(x, x++);
System.out.println("enter"+x);
}
});
}
}
};
new Thread(runnable).start();
}
I am trying to animate digits on a textview using timely text view, however when I call startTimerThread from my code which is outside of onCreate neither do I get the text view to display not does the system.out execute. What do I miss here?
try like this
Handler handler = new Handler();
int delay=1000;
Runnable rann=new Runnable() {
#Override
public void run() {
//Write Your logic here which you want to perform periodically
System.out.println("Handler is running : ");
//to call the same thread repeatedly calling handler again
handler.postDelayed(rann, delay);
}
};
private void startHandler() {
//here the handler will executes the rannable after that particulary delay milli seconds
handler.postDelayed(rann, delay);
}
private void stopHandler() {
handler.removeCallbacks(rann);
}
public class Signal2NoiseRatio
{
public ImagePlus SingleSNR(ImagePlus imagePlus) throws InterruptedException
{
new Thread()
{
#Override public void run()
{
JFrame imageFrame = new JFrame("ROI");
Container imageFrame_Container = imageFrame.getContentPane();
IIImagePanel imagePanel = new IIImagePanel();
imageFrame_Container.add(imagePanel);
imagePanel.setImage(imagePlus.getImage());
imagePanel.getDisplayedImage();
imageFrame.setVisible(true);
final SNRSingleImageListener sNRSingleListener = new SNRSingleImageListener(imagePanel);
imagePanel.addMouseListener(sNRSingleListener);
imagePanel.addMouseMotionListener(sNRSingleListener);
}
}.start();
new Thread()
{
#Override public void run()
{
for (int i = 0; i <= 2000; i++)
{
System.out.println("schleife "+i);
// ask if useractions are done ..
}
synchronized( Signal2NoiseRatio.this )
{
Signal2NoiseRatio.this.notifyAll();
}
}
}.start();
synchronized (this)
{
this.wait();
// if userinteractions are done, go on
}
return imagePlusToProcess;
}
}
The first new Thread() perform a frame which presents an image in it. My intention was to present the image in a new thread to wait for some user interactions on the image. But the code leads the frame to a white window and the image is not visible and the frame is not usable.
In the second thread I want ask in a short interval if the user actions are done.
It is not really a nice solution but it is be possible? what's wrong here?
Thank you stackoverflow!
I can see a few problems here:
1.If this
synchronized (this)
{
this.wait();
// if userinteractions are done, go on
}
is happening on the UI thread, then you will block it from receiving user input (or doing anything else) until the object is signaled.
2.This part seems pretty much overcomplicated:
new Thread() {
#Override
public void run() {
for (int i = 0; i <= 2000; i++) {
System.out.println("schleife " + i);
// ask if useractions are done ..
}
synchronized (Signal2NoiseRatio.this) {
Signal2NoiseRatio.this.notifyAll();
}
}
}.start();
synchronized (this) {
this.wait();
// if userinteractions are done, go on
}
Just use:
Thread t = new Thread() {
#Override
public void run() {
for (int i = 0; i <= 2000; i++) {
System.out.println("schleife " + i);
// ask if useractions are done ..
}
}
}.start();
t.join();
Unless you're signaling more than what you had above. But again, this is redundant, since starting a thread only to wait for it to finish does not make much sense...
Problem solved.
The invoker of the method was an AWT-Thread. I created a new Thread for the invoker and so the AWT-Thread was not blocked and the then frame and image could present correctly.
Thank you all for your help.