My app works with a few pictures. I want to take a new one every few seconds and add it to the pictures I work with. So I wrote this code, using an own Thread for the waiting time, so the ui won't freeze.
Handler handler = new Handler();
int time = 500;
for (int cnt = 10000; cnt > 0; cnt -= time) {
// Execute the code in run after time [ms] passed
handler.postDelayed(new Runnable() {
public void run() {
mainTask();
}
}, time);
}
Why does my ui freeze until the for loop ends? Usually the shown pictures should be updated in the mainTask()
Thanks for your help!
[EDIT]
It is working now, I created a class that implements Runnable and let it call itself:
Handler handler = new Handler();
class DelayedTask implements Runnable {
int cnt, time;
Handler handler;
DelayedTask(int c, int t, Handler h) {cnt=c; time=t; handler=h;}
public void run() {
mainTask();
if (cnt > 0) {
cnt -= time;
handler.postDelayed(new DelayedTask(cnt, time, handler), time);
}
}
}
handler.postDelayed(new DelayedTask(cnt,time,handler), time);
You're scheduling 10000/500 Runnables in a very short time, all firing after 500ms, at the same time. This is probably not what you want.
Instead, you want to schedule the next Runnable when the current Runnable fires:
handler.postDelayed(new Runnable() {
#Override
public void run() {
mainTask();
if(someCondition) {
handler.postDelayed(this, 500);
}
}
}, 500);
Now, mainTask will fire every ~500ms.
I am not too sure, but I think the handler goes like this:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
mainTask();
handler.postDelayed(this, interval);
}
}, interval);
Related
UPDATE : The code is working only that I dint init the textview, but this question is answered so I cant remove it either. So I will leave this question as it is for anyone trying to implement a Timertask with handler that makes use of Looper.getMainLooper that directly attaches it to the UI THREAD.
OLD QUERY :Hello guys I am trying to implement a timer that runs a task which has a handler.
I am using it to update the UI every second.
This is what I am implementing:
private void setRepeatingAsyncTask() {
handler = new Handler(Looper.getMainLooper());
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
i++;
tview.setText(String.valueOf(i));
} catch (Exception e) {
// error, do something
}
}
});
}
};
timer.schedule(task, 0, 1000); // interval of one minute
}
when I make setRepeatingAsyncTask() on create or somewhere else like button clicklistner, etc either the timer or the handler is not starting.
Please help new to android!
I used Handler to process the task every 1 sec, Using just Handler:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
//some task
handler.postDelayed(this, 1000); //looping is every 1 secs
}
}, 0); //initial delay of 0
I want to print the current second using a handler. I record a video for exactly 10 seconds and want to set the text of a TextView every second.
Recording 10 seconds works like that:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
stopRecordingVideo();
}
}, 11000); // don't know why 11000 but it only works this way
After the 10 seconds the method stopRecordingVideo() gets executed. So how can I change the text every second of the TextView?
Working answer:
int t = 0;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
t++;
textView.setText(getString(R.string.formatted_time, t));
if(t<10) {
handler.postDelayed(this, 1000);
}
}
}, 1000);
Where formatted_time is something like that:
<string android:name="formatted_time">%d seconds</string>
To print text every second, you can use CountDownTimer. But if you want to achieve this with try below code:
void startTime(){
//Post handler after 1 second.
handler.postDelayed(runnable, 1000);
}
int totalDelay=0;
Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
totalDelay++;
if(totalDelay<=10){
//If total time is less then 10 second execute handler again after 1 second
handler.postDelayed(runnable, 1000);
}
textView.setText(totalDelay+" Second");
}
};
Try this, basically do the increment in a worker thread, but updating the text view is done by main's thread handler.
Thread worker= new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// stop recording after 10 seconds
if (i == 9) {
handler.post(new Runnable() {
#Override
public void run() {
stopRecordingVideo();
}
});
}
else{
// set text for each second
handler.post(new Runnable() {
#Override
public void run() {
textView.setText(String.valueOf(i+1));
}
});
}
}//ends for()
worker.start()
How can i make code sleep without threading / runnable. I require to modify layout in a android app, operate a method and reverse layout changes again. However this methods contains counters, whenever i have a inner class, like a runnable timertask or something simular the variable needs to be final, but then i cannot increase the counters.
ChangeLayout();
int round = 0;
while (isPlaying && round < 24){
round++;
int specificOccurrence = 0;
while (isPlaying && specificOccurence < 8) {
if (somethingSpecific){
specificOccurence++;
}
// operates this while somehow with a 1 second break;
// after that just continue.
waitASecondSomehow();
}
}
ReverseLayoutChanges();
Use a Handler to schedule work on the main thread using postDelayed:
Handler h = new Handler();
h.postDelayed(runnable, delayInMillis);
The runnable above is a Runnable instance that does what you want to execute on the main thread. Keep posting it at each interval, perhaps repeated within the runnable itself to schedule the next iteration.
You should use Timer for this.
Timer mUiUpdateTimer;
TimerTask uiUpdateTask;
int mistakes=0;
int periodTime=1000;
private void createTimeHandler()
{
mUiUpdateTimer = new Timer();
final Handler uiUpdateHandler = new Handler();
final Runnable uiUpdateRunnable = new Runnable() {
#Override
public void run() {
// other jobs
mistakes++;
}
};
uiUpdateTask = new TimerTask() {
#Override
public void run() {
//for safe UI handling
uiUpdateHandler.post(uiUpdateRunnable);
}
};
mUiUpdateTimer.scheduleAtFixedRate(uiUpdateTask, 0, periodTime);
}
Just Add bellow Handler inside your try block
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
mistakes++;
}
}
}, 3000);
I am updating a counter in thread and its working fine.
But when the phone is in sleep and activity runs after aquiring wakelock, the thread not updates the UI using counter.
Here is my function where I am updating the view value.
private void updateTimeInBackground() {
new Thread(new Runnable() {
#Override
public void run() {
startAlarm();
int counter = MINUTE;
// in this function Im using the runOnUiThread(...) to update the view and also used TextView.post(...)
updateTextViewValue(counter);
if (isDismissed)
return;
updateOverlayForAlert();
counter = 0;
int minutes = 1;
vibrator.vibrate(1000);
// in this function Im using the runOnUiThread(...) to update the view and also used TextView.post(...)
updateTextViewValue(counter, minutes);
}
}).start();
Any suggestions? or hint?
Use TimerTask which will continue to run in the background.
Hope this helps.
Use Handler and Runnable instead of Thread
final Handler handler=new Handler();
runnable=new Runnable() {
#Override
public void run() {
handler.postDelayed(runnable, 5000);
// your code
}
};
runnable.run();
Here is a code which I want to repeat 50 times after every 3 seconds. if I am calling this function with 'for' loop or 'while' loop it is not working properly Please give me suggestion.
for (int i = 0; i < 50; i++) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Generate_Ballon();
}
}, delay);
}
You can use CountDownTimer
See Example,
new CountDownTimer(150000, 3000)
{
public void onTick(long millisUntilFinished)
{
// You can do your for loop work here
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Here onTick() method will get executed on every 3 seconds.
You should use Handler's postDelayed function for this purpose. It will run your code with specified delay on the main UI thread, so you will be able to update UI controls.
private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
...
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
updateStatus(); //this function can change value of mInterval.
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
private int count = 50;
private Handler handler = new Handler();
private Runnable r = new Runnable() {
public void run() {
Generate_Ballon();
if (--count > 0) {
handler.postDelayed(r, delay);
}
}
};
handler.postDelayed(r, delay);