java - Why does my simple timer app keep getting faster each time I pause? -
ok, thought problem each time press stop , start, new runnable created, have multiple runnable running @ same time, updating timer quicker , quicker each time. doesn't seems problem: changed code adding boolean "running" pressing start/stop changes boolean variable. in way, think 1 runnable running. still gets faster click start/stop several times in row. can tell me problem is?
package com.example.timernew; import android.app.activity; import android.os.bundle; import android.os.handler; import android.view.menu; import android.view.menuitem; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; public class mainactivity extends activity { handler h=new handler(); textview t; button start, stop,reset; boolean running; runnable run=new runnable() { @override public void run() { updatetime(); } };; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); t = (textview) findviewbyid(r.id.textarea); start = (button) findviewbyid(r.id.start_button); stop=(button) findviewbyid(r.id.stop_button); running=false; h.post(run); start.setonclicklistener(new onclicklistener(){ @override public void onclick(view v){ if(running==false){ running=true; } } }); stop.setonclicklistener(new onclicklistener(){ @override public void onclick(view v){ if(running==true){ running=false; } } }); } public void updatetime() { if(running==true){ t.settext("" + (integer.parseint(t.gettext().tostring()) +1)); h.postdelayed(run, 1000);} } }
i added call updatetime() in start button onclicklistenter , have had no problems count continuing after hitting stop. after waiting 10+ seconds, hitting start again starts continues left off.
i did notice value increase twice in quick succession if hit start within 1 second of hitting stop. because hitting start calls updatetime() , posted runnable's delay has not finished, when does, increments time.
a better bet use asynctask:
package com.example.timernew; import android.app.activity; import android.os.asynctask; import android.os.bundle; import android.os.handler; import android.util.log; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; public class mainactivity extends activity { handler h=new handler(); textview t; button start, stop,reset; volatile boolean running; updatetimetask mupdatetimetask; int counter = 0; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); t = (textview) findviewbyid(r.id.textarea); start = (button) findviewbyid(r.id.start_button); stop=(button) findviewbyid(r.id.stop_button); running=false; start.setonclicklistener(new onclicklistener(){ @override public void onclick(view v){ if (null == mupdatetimetask) { mupdatetimetask = new updatetimetask(); mupdatetimetask.execute(); } } }); stop.setonclicklistener(new onclicklistener(){ @override public void onclick(view v){ if(null != mupdatetimetask) { mupdatetimetask.cancel(true); mupdatetimetask = null; } } }); } public class updatetimetask extends asynctask<void, void, void> { protected void doinbackground(void... params) { while (true) { try { thread.sleep(1000); } catch (interruptedexception ie) { log.e("timer app", "a problem occurred while sleeping or task cancelled", ie); return null; } counter++; publishprogress(); } } @override protected void onprogressupdate(void... values) { super.onprogressupdate(values); t.settext(string.valueof(counter)); } } }
to answer question changing boolean value , calling updatetime():
in original code, updatetime() called during oncreate() @ line:
h.post(run);
and since have boolean set false, nothing , finishes running.
now, suppose add call updatetime() inside start_button click listener , hit start, stop, start in quick succession. here's what's happening (assuming each happen @ 100ms intervals):
0ms
click start sets boolean true, calls updatetime()
10ms
updatetime() called, boolean true, changes text , posts runnable run in 1000ms
100ms click stop sets boolean false
200ms click start sets boolean true, calls updatetime()
210ms updatetime() called, boolean true, changes text , posts runnable run in 1000ms
1010ms first posted runnable runs, sees boolean true, changes text , posts runnable run in 1000ms
1210ms second posted runnable runs, sees boolean true, changes text, , posts runnable
at point less 1.3 seconds in , count @ 3 seconds. now, text changed approximately every n + .1 , n + .2 seconds now.
Comments
Post a Comment