How to change the sleep / timer thread delay in android at runtime?

What I was trying to do was reduce the timer delay every time the counter becomes a multiple of 5. But, as soon as the code entered the if block, it stopped increasing the timer. I can not understand what is happening.

This is the code

thread=new Thread(){ public void run(){ try{ if(count%5==0) timre--; else{ //do nothing } //*******PROGRESS UPDATE********// for(t=0;t<=100;t++) { sleep((timre) / 100); progress.setProgress(t); t += 1; } //****PROGRESS UPDATE OVER****// } catch (InterruptedException e) { e.printStackTrace(); } finally { finish(); } }//run ends };//thread ends thread.start();//timer starts 
+6
source share
6 answers

Thread.sleep () is not guaranteed. This means that he may or may not sleep for a long time for various reasons that are not relevant to the topic for this issue.

If you are looking for a network for the “timer in android”, you will probably land on these two: https://developer.android.com/reference/java/util/Timer.html and https://developer.android.com/ reference / java / util / concurrent / ScheduledThreadPoolExecutor.html

You can test them, but I would not use them, because they provide many other functions, as the name suggests ("ScheduledThreadPoolExecutor"). You do not need this, since it will most likely be used for large systems with a large number of threads, etc.

If I understand your code correctly, you are trying to update the progress bar. For what you are trying to do, I would suggest using a handler. One of the main uses of the handler is to plan messages and executables that will be executed as some points in the future, as indicated in the documents: http://developer.android.com/reference/android/os/Handler.html

I would do it like this:

  int counter = 0; int delayInMs = 5000; // 5 seconds Handler timer = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) { counter++; // If the counter is mod 5 (or whatever) lower the delay if (counter % 5 == 0) { delayInMs/=100; // Or any other calculation. } // If the counter reaches 100 the counting will not continue. if (counter <= 100) { // If the counter has not reached the condition to stop, the handler // will call the timer again with the modified (or not) delay. timer.sendEmptyMessageDelayed(0, delayInMs); // Change progress updateProgress(counter); } return true; } }); // ... // Somwhere in the code to start the counter timer.sendEmptyMessageDelayed(0, delayInMs); // starts the timer with the initial 5 sec delay. 

One more thing. In the line where you have this code:

 progress.setProgress(t); 

Be careful when invoking user interface elements from other threads; this is the source of a lot of headache. If your handler is in another thread, you must transfer this call to the function and make sure that it is called from the main thread (i.e., the UI Thread). Many ways to achieve this (not always necessary). One of them is as follows:

 private void updateProgress(int counter) { WhateverActivity.this.runOnUiThread(new Runnable() { public void run() { progress.setProgress(counter); } }); } 
+5
source

Themes (and sleep() ) are complicated in android. Try instead of CountDownTimer

 CountDownTimer counter; startTimer(); counter.start(); private void startTimer() { counter = new CountDownTimer(4000, 500){ @Override public void onFinish() { **DO YOUR STUFF HERE** } @Override public void onTick(long millisUntilFinished) { } }; } 

Call the startTimer() function startTimer() you want, and run counter at the same time.

+6
source

Could you explain what timre and count are when it starts? I can assume that they are 0 , in which case

 if(count%5==0) //Immediately true. 0 mod 5 == 0. timre--; // 0-- = -1? else{ //do nothing } 

-0.01 that mean your for loop will sleep for -0.01 milliseconds?

 for(t=0;t<=100;t++) { sleep((timre) / 100); progress.setProgress(t); t += 1; } 

This explains why it immediately runs the setProgress method. But hey, I could be wrong. Let us know that these variables are initialized as or that they are currently set when the code hits!

Thanks,

+2
source

I think you should include an if block inside a for loop. When you wrote the code, the if block is only executed when the thread starts, so it is executed only once. Therefore, inside the loop, the temporary variable never changes.

I think your code should look like this:

 thread=new Thread(){ public void run(){ try{ //*******PROGRESS UPDATE********// for(t=0;t<=100;t++) { if(count%5==0) timre--; sleep((timre) / 100); progress.setProgress(t); t += 1; } //****PROGRESS UPDATE OVER****// } catch (InterruptedException e) { e.printStackTrace(); } finally { finish(); } }//run ends };//thread ends thread.start();//timer starts 
+2
source

Something like this should work:

 thread=new Thread(){ ++ private float timre; ++ public void setTimre(float timre) { ++ this.timre = timre; ++ } public void run(){ try{ if(count%5==0) timre--; else{ //do nothing } //*******PROGRESS UPDATE********// for(t=0;t<=100;t++) { sleep((timre) / 100); progress.setProgress(t); t += 1; } //****PROGRESS UPDATE OVER****// } catch (InterruptedException e) { e.printStackTrace(); } finally { finish(); } }//run ends };//thread ends thread.start(); ++ if(condition to change the sleeping time) { ++ try { ++ thread.interrupt(); ++ catch(Exception e) { ++ e.doSomethingCoolWithit(); ++ } ++ thread.setTimre(newTimre); ++ thread.start(); ++ } } 

Although this will probably fail when you try to call thread.start () a second time, and you may need to create a new thread.

+2
source

as @Amaresh suggested, you should use CountDownTimer to complete the task. Your implementation is wrong in two ways.

  • There is no guarantee that the stream can always be executed, and the time in the stream may not be the same as the so-called real-time time. You can find more information about sleep and time from here .

  • I assume that you are going to update the user interface when changing progress. In this case, CountDownTimer saves you the trouble of calling back to the main thread without additional handlers.

If you're interested, you can check the implementation of CountDownTimer from the Android source code, this is straightforward and easy to understand.

If your code runs on a resource-intensive service, make sure your timer runs when the device goes into standby mode. In this case, you may need to wake up paired with the WakefulBroadcastReceiver .

+2
source

Source: https://habr.com/ru/post/989083/


All Articles