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();
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 have a button(in say Activity 1), which when clicked should start a service (eg Service 1). But there must be a delay of 5 seconds before the service starts. I achieved this using SystemClock.sleep(5000) in the onStartCommand of the service. This worked properly.
Now I want to add the functionality that if the button is clicked again(even before the 5 seconds end), the service WILL NOT BE STARTED.
Any ideas how to do this?
(Edit : Please read the entire question before marking it as a duplicate. Thanks)
You can use handler with post delayed to achieve your goal. Make your button disable and enable it after five seconds along with starting your service. You can implement the following code:
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button.setEnabled(false);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//start your service here
button.setEnabled(true);
}
}, 5000);
}
});
Above code will disable your button for 5 second and will start your service after 5 second.
I'd use a util class similar to the following. Pass it in a runnable and a delay in ms and you can call stop() on it to cancel before it has run. You can also call restart() if you want to restart your timer. I use it for things like auto showing/hiding controls on an immersive view.
public class DelayableRunnable{
int mDelay = 0;
Handler mHandler = new Handler();
Runnable mRunnable;
boolean mIsRunning = false;
public DelayableRunnable(Runnable runnable, int delay){
mRunnable = runnable;
mDelay = delay;
}
public void setNewDelay(int delay){
mDelay = delay;
}
public void start(){
if(mIsRunning) {
stop();
}
mHandler.postDelayed(mRunnable, mDelay);
mIsRunning = true;
}
public void stop(){
mHandler.removeCallbacks(mRunnable);
mIsRunning = false;
}
public void restart(){
stop();
start();
}
}
You can use Handler.postDelayed function for delayed actions in Android enviroment (better than plan java methods)
final Handler handler = new Handler(); // or use existed one your_view.getHandler()
handler.postDelayed(new Runnable() {
#Override
public void run() {
//start your service
}
}, 5000 /* 5s * 1000ms */);
Or simpler use you view function (work same as above):
your_view.postDelayed(new Runnable() {
#Override
public void run() {
//start your service
}
}, 5000 /* 5s * 1000ms */);
A facility for threads to schedule tasks for future execution in a background thread. Tasks may be scheduled for one-time execution, or for repeated execution at regular intervals void schedule (TimerTask task,long delay) Schedules the specified task for execution after the specified delay.
new Timer().schedule(new TimerTask() {
#Override
public void run() {
alertDialog.dismiss();
startActivity(new Intent(****.this,*********.class));
}
},5000);
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);
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);
I have tried multiple ways to have a single persistent timer update the ui in multiple activities, and nothing seems to work. I have tried an AsyncTask, a Handler, and a CountDownTimer. The code below does not execute the first Log.i statement.... Is there a better way to start the timer (which must be called from another class) in Main (which is the only persistent class)?
public static void MainLawTimer()
{
MainActivity.lawTimer = new CountDownTimer(MainActivity.timeLeft, 1000)
{
public void onTick(long millisUntilFinished)
{
Log.i("aaa","Timer running. Time left: "+MainActivity.timeLeft);
MainActivity.timeLeft--;
if(MainActivity.timeLeft<=0)
{
//do stuff
}
else
{
//call method in another class
}
}
public void onFinish()
{ }
}.start();
}
To clarify my problem:
When I run the code the Log.i("aaa","Timer running") statement is never shown in the log, and the CountDownTimer never seems to start. MainLawTimer is called from another class only (not within the same class.
For CountDownTimer
http://developer.android.com/reference/android/os/CountDownTimer.html
You can use a Handler
Handler m_handler;
Runnable m_handlerTask ;
int timeleft=100;
m_handler = new Handler();
#Override
public void run() {
if(timeleft>=0)
{
// do stuff
Log.i("timeleft",""+timeleft);
timeleft--;
}
else
{
m_handler.removeCallbacks(m_handlerTask); // cancel run
}
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
Timer
int timeleft=100;
Timer _t = new Timer();
_t.scheduleAtFixedRate( new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() //run on ui thread
{
public void run()
{
Log.i("timeleft",""+timeleft);
//update ui
}
});
if(timeleft>==0)
{
timeleft--;
}
else
{
_t.cancel();
}
}
}, 1000, 1000 );
You can use a AsyncTask or a Timer or a CountDownTimer.
Thank you all for your help, I discovered the error in my code... timeLeft was in seconds rather then milliseconds. Since timeLeft was under 1000 (the wait period) the timer never started.