I was using a CountDownTimer for some countdown functionality I have in my Activity. I decided to move away from CountDownTimer and use ScheduledThreadPoolExecutor because CountDownTimers can't cancel themselves in onTick().
For some reason, my Runnable in the following code only executes once. I'm not sure why it isn't executing multiple times. The destroyCountdownTimer() function is not getting hit.
private ScheduledThreadPoolExecutor mCountdownTimer;
private Tick mTick;
class Tick implements Runnable {
#Override
public void run() {
Log.e("tick", String.valueOf(mAccumulatedMilliseconds));
mAccumulatedMilliseconds += 1000;
populateTimeAccumulated();
populateTimeRemaining();
updatePercentages();
if (mTotalMilliseconds <= mAccumulatedMilliseconds) {
destroyCountdownTimer();
}
}
}
private void startCountdown() {
if (mAccumulatedMilliseconds < mTotalMilliseconds) {
mCounterIsRunning = true;
if (mCountdownTimer == null) {
mCountdownTimer = new ScheduledThreadPoolExecutor(1);
}
if (mTick == null) {
mTick = new Tick();
}
mCountdownTimer.scheduleAtFixedRate(mTick, 1000, 1000, TimeUnit.MILLISECONDS);
}
}
private void destroyCountdownTimer() {
if (mCountdownTimer != null) {
mCountdownTimer.shutdownNow();
mCountdownTimer = null;
}
if (mTick != null) {
mTick = null;
}
}
The documentation says:
If any execution of the task encounters an exception, subsequent executions are suppressed.
Add try-catch block to your Tick runnable.
Related
public void startCountdownTimer() {
currentCountdown = startCountdown;
// stopTimer=false;
if (stopTimer == true) {
return;
}
for (int i = 1; i <= startCountdown + 1; i++) {
task = new TimerTask() {
#Override
public void run() {
countdownHandler.post(doA);
}
};
countdownTimer = new Timer();
countdownTimer.schedule(task, i * 1000);
}
}
final Runnable doA = new Runnable() {
#Override
public void run() {
//reset timer when switching to another question
if (currentCountdown != -1 && btn_next.getText().equals("CHECK") && stopTimer != true) {
if (currentCountdown == 0) {
relative_stop.setVisibility(View.INVISIBLE);
currentCountdown = startCountdown;
btn_next.setText("NEXT");
toast = Toasty.warning(getApplicationContext(), "Time's UP", 1000);
toast.show();
toast = Toasty.info(getApplicationContext(), correctAnswer, 1000);
toast.show();
countdownTimer.cancel();
countdownTimer.purge();
}
tv_timer.setText("" + currentCountdown);
currentCountdown--;
}
}
};
I'm trying to make a timer that counts down for 10 seconds, it works normally when it runs for the first time, and when it runs consecutively, the timer caused by delay suddenly speeds up.
My requirements are to poll a web service every fixed interval. After instantiating the handler as a private field of the class, I'm doing this in the onCreate method of the main activity:
if (handler != null) {
handler.post(new Runnable() {
#Override
public void run() {
String sessionId = SharedPreferencesHelper.getSessionId(MainActivity.this);
if (sessionId != null && !sessionId.isEmpty()) {
if (Utils.isNetworkAvailable(MainActivity.this)) {
restHandler.getUnreadMessages(sessionId);
}
handler.postDelayed(this, Constants.CHAT_POLLING_REFRESH_DELAY);
} else {
handler.removeCallbacks(this);
}
}
});
}
Then onDestroy:
if (handler != null) {
handler.removeCallbacksAndMessages(null);
handler = null;
}
The backend is complaing that sometimes the sessionId passed is empty or null. How can this be possible? I'm using retrofit. Bonus question: can I have problems with MainActivity.this context reference when app goes in background?
I download gocoder android example and run the BitmapOverlayActivity, everything is ok but when I try to update the WZBitmap using WZBitmap.setBitmap() like:
private Runnable runnable = new Runnable() {
#Override
public void run() {
if (mWZBitmap != null) {
if (System.currentTimeMillis() % 2 == 0) {
mWZBitmap.setBitmap(overlayBitmap1);
} else {
mWZBitmap.setBitmap(overlayBitmap2);
}
}
handler.postDelayed(runnable, 5000);
}
};
private Handler handler = new Handler();
and the camera only shows black view:
I m facing issue in fitness app after 1 hr timertask runs slow or sometimes it runs too fast like it increase 2 second simantaneously please someone suggest stable solution ..I am saving user history when ever I get new location any help is appreciated
public void reStartTimerTask(final boolean onCreate) {
if (Validator.isNull(timer)) {
if (preferences.isGps()) {
IntentFilter intentFilter = new IntentFilter(Util.LOCAL_RECEIVER);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
workoutReceiver = new WorkoutReceiver();
registerReceiver(workoutReceiver, intentFilter);
if (!onCreate) {
if (!Util.isGPSEnabled(this)) {
displayGPSAlert();
}
if (!preferences.isTryOut()) {
Request.getRequest().sendRequest(Request.GET_ALL_TRACE_USER, this, this, RequestParameterBuilder.buildMapForUserId(this));
}
}
}
timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
if (preferences.isGps()) {
WorkoutServiceHelper.getWorkoutServiceHelper(MainActivity.this).connect();
}
if (!preferences.isWorkoutPaused()) {
history.duration++;
history.calories = HWUtil.calculateCalorie(history, MainActivity.this);
history.cascadeSave();
}
if (history.duration % 5 == 0 && preferences.isTrace() && !preferences.isRequestSent()) {
//Sync record every five second
UserHistoryModel historyModel = history.loadAll();
if (Validator.isNotNull(historyModel)) {
UserHistory uh = convertUserHistoryModelToUserHistory(historyModel);
/*
don't set history pictures when tracing
*/
uh.setHistoryPictures(null);
uh.setId(uh.getUniqueId());
preferences.setRequestSent(true);
Request.getRequest().sendJsonRequest(Request.ADD_USER_HISTORY, MainActivity.this, MainActivity.this, RequestParameterBuilder.buildJsonObjectFromUserHistory(uh));
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
if (getSupportFragmentManager().findFragmentByTag(TabFragment.class.getName()) != null) {
TabFragment tabFragment = (TabFragment) getSupportFragmentManager().findFragmentByTag(TabFragment.class.getName());
if (tabFragment.getCurrentFragment() instanceof UpdateListener) {
((UpdateListener) tabFragment.getCurrentFragment()).update();
}
} else if (getSupportFragmentManager().findFragmentByTag(FullMapFragment.class.getName()) != null) {
FullMapFragment mapFragment = (FullMapFragment) getSupportFragmentManager().findFragmentByTag(FullMapFragment.class.getName());
mapFragment.update();
}
}
});
}
};
timer.scheduleAtFixedRate(task, 0, 1000);
}
}
whenever user starts any workout/after pause i m calling this method
In my application, I have a button that starts an AsyncTask that downloads data with coordinates for google maps, then draws a marker on the map at the following coordinates. I want to run this every 10 seconds until the user presses the button again.
Here's my code for the handler:
class handleMap{
Handler mHandler = new Handler();
Runnable mTask = new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
while(btnRefreshPressed == false){
try{
new getGoogleMap().execute();
mHandler.postDelayed(mTask, INTERVAL);
Thread.sleep(INTERVAL);
} catch(Exception e){
System.out.println(e.toString());
}
}
}
};
public void starReapetingClass (){
hMap.starReapetingClass();
}
public void stopDoing(){
mHandler.stopDoing();
}
}
And in the menubutton where it is called:
case R.id.id_Refresh:
handleMap hMap = new handleMap();
if(btnRefreshPressed == true){
menuItem = item;
menuItem.setActionView(R.layout.progressbar);
menuItem.expandActionView();
fRun += 1;
btnRefreshPressed = false;
hMap.run();
}else if(btnRefreshPressed == false){
if(fRun > 0){
menuItem.collapseActionView();
menuItem.setActionView(null);
}
btnRefreshPressed = true;
hMap.stopHandler();
}
This currently causes the application to freeze, and the system outputs a dialog saying that the app isn't responding, and asking if I want to close or wait.
I suspect it has to with the while statement, but I don't get any errors in logcat.
Thanks in advance.
Just use:
private int mSampleDurationTime = 10000;
private boolean continueToRun = true;
mHandler.postDelayed(mRunnable, mSampleDurationTime);
where mRunnable is your task:
private final Runnable mRunnable = new Runnable() {
//...
public void run() {
...
if(continueToRun == true){
mHandler.postDelayed(mRunnable, mSampleDurationTime);
}
}
...
};
First time you call postDelayed and invoke new Runnable(). After, if you want to continue,
call the same method into run()