Czy ktoś może podać prosty przykład aktualizacji pola tekstowego co sekundę?
Chcę zrobić latającą piłkę i muszę obliczać / aktualizować współrzędne piłki co sekundę, dlatego potrzebuję jakiegoś timera.
Nie rozumiem nic z tutaj .
Czy ktoś może podać prosty przykład aktualizacji pola tekstowego co sekundę?
Chcę zrobić latającą piłkę i muszę obliczać / aktualizować współrzędne piłki co sekundę, dlatego potrzebuję jakiegoś timera.
Nie rozumiem nic z tutaj .
Odpowiedzi:
ok, ponieważ nie zostało to jeszcze wyjaśnione, istnieją 3 proste sposoby radzenia sobie z tym. Poniżej znajduje się przykład pokazujący wszystkie 3, a na dole przykład pokazujący tylko metodę, która moim zdaniem jest lepsza. Pamiętaj także o wyczyszczeniu zadań w trybie onPause, w razie potrzeby zapisując stan.
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Handler.Callback;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class main extends Activity {
TextView text, text2, text3;
long starttime = 0;
//this posts a message to the main thread from our timertask
//and updates the textfield
final Handler h = new Handler(new Callback() {
@Override
public boolean handleMessage(Message msg) {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text.setText(String.format("%d:%02d", minutes, seconds));
return false;
}
});
//runs without timer be reposting self
Handler h2 = new Handler();
Runnable run = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text3.setText(String.format("%d:%02d", minutes, seconds));
h2.postDelayed(this, 500);
}
};
//tells handler to send a message
class firstTask extends TimerTask {
@Override
public void run() {
h.sendEmptyMessage(0);
}
};
//tells activity to run on ui thread
class secondTask extends TimerTask {
@Override
public void run() {
main.this.runOnUiThread(new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - starttime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
text2.setText(String.format("%d:%02d", minutes, seconds));
}
});
}
};
Timer timer = new Timer();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text = (TextView)findViewById(R.id.text);
text2 = (TextView)findViewById(R.id.text2);
text3 = (TextView)findViewById(R.id.text3);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button)v;
if(b.getText().equals("stop")){
timer.cancel();
timer.purge();
h2.removeCallbacks(run);
b.setText("start");
}else{
starttime = System.currentTimeMillis();
timer = new Timer();
timer.schedule(new firstTask(), 0,500);
timer.schedule(new secondTask(), 0,500);
h2.postDelayed(run, 0);
b.setText("stop");
}
}
});
}
@Override
public void onPause() {
super.onPause();
timer.cancel();
timer.purge();
h2.removeCallbacks(run);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
}
}
najważniejszą rzeczą do zapamiętania jest to, że interfejs użytkownika można modyfikować tylko z głównego wątku interfejsu użytkownika, więc użyj programu obsługi lub activity.runOnUIThread (Runnable r);
Oto, co uważam za preferowaną metodę.
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TestActivity extends Activity {
TextView timerTextView;
long startTime = 0;
//runs without a timer by reposting this handler at the end of the runnable
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
timerTextView.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this, 500);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_activity);
timerTextView = (TextView) findViewById(R.id.timerTextView);
Button b = (Button) findViewById(R.id.button);
b.setText("start");
b.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("stop")) {
timerHandler.removeCallbacks(timerRunnable);
b.setText("start");
} else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("stop");
}
}
});
}
@Override
public void onPause() {
super.onPause();
timerHandler.removeCallbacks(timerRunnable);
Button b = (Button)findViewById(R.id.button);
b.setText("start");
}
}
To jest proste! Tworzysz nowy licznik czasu.
Timer timer = new Timer();
Następnie rozszerzasz zadanie timera
class UpdateBallTask extends TimerTask {
Ball myBall;
public void run() {
//calculate the new position of myBall
}
}
A następnie dodaj nowe zadanie do Timera z pewnym interwałem aktualizacji
final int FPS = 40;
TimerTask updateBall = new UpdateBallTask();
timer.scheduleAtFixedRate(updateBall, 0, 1000/FPS);
Oświadczenie: To nie jest idealne rozwiązanie. Jest to rozwiązanie wykorzystujące klasę Timer (zgodnie z zapytaniem OP). W zestawie Android SDK zaleca się użycie klasy Handler (w zaakceptowanej odpowiedzi znajduje się przykład).
Jeśli musisz także uruchomić swój kod w wątku interfejsu użytkownika (a nie w wątku licznika czasu), zajrzyj na blog: http://steve.odyfamily.com/?p=12
public class myActivity extends Activity {
private Timer myTimer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
TimerMethod();
}
}, 0, 1000);
}
private void TimerMethod()
{
//This method is called directly by the timer
//and runs in the same thread as the timer.
//We call the method that will work with the UI
//through the runOnUiThread method.
this.runOnUiThread(Timer_Tick);
}
private Runnable Timer_Tick = new Runnable() {
public void run() {
//This method runs in the same thread as the UI.
//Do something to the UI thread here
}
};
}
Jeśli po prostu chcesz zaplanować odliczanie do czasu w przyszłości z regularnymi powiadomieniami o odstępach czasu po drodze, możesz użyć klasy CountDownTimer, która jest dostępna od poziomu API 1.
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
editText.setText("Seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
editText.setText("Done");
}
}.start();
SS:MiMi
? Dzięki
Oto prosty kod dla timera:
Timer timer = new Timer();
TimerTask t = new TimerTask() {
@Override
public void run() {
System.out.println("1");
}
};
timer.scheduleAtFixedRate(t,1000,1000);
Myślę, że możesz to zrobić w Rx sposób:
timerSubscribe = Observable.interval(1, TimeUnit.SECONDS)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
//TODO do your stuff
}
});
I anuluj to tak:
timerSubscribe.unsubscribe();
Rx Timer http://reactivex.io/documentation/operators/timer.html
Ponieważ to pytanie wciąż przyciąga wielu użytkowników z wyszukiwarki Google (o zegarze Androida), chciałbym wstawić dwie monety.
Przede wszystkim klasa Timer będzie przestarzała w Javie 9 (przeczytaj zaakceptowaną odpowiedź) .
Urzędnik zaproponował sposobem jest użycie ScheduledThreadPoolExecutor który jest bardziej skuteczny i dysponuje bogatym w które można dodatkowo komendy rozkład jazdy po danym opóźnienie lub okresowo wykonywać. Ponadto zapewnia dodatkową elastyczność i możliwości ThreadPoolExecutor.
Oto przykład użycia prostych funkcji.
Utwórz usługę executora:
final ScheduledExecutorService SCHEDULER = Executors.newScheduledThreadPool(1);
Po prostu zaplanuj uruchomienie:
final Future<?> future = SCHEDULER.schedule(Runnable task, long delay,TimeUnit unit);
Możesz teraz użyć, future
aby anulować zadanie lub sprawdzić, czy zostało wykonane, na przykład:
future.isDone();
Mam nadzieję, że okaże się to przydatne do tworzenia zadań w Androidzie.
Kompletny przykład:
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Future<?> sampleFutureTimer = scheduler.schedule(new Runnable(), 120, TimeUnit.SECONDS);
if (sampleFutureTimer.isDone()){
// Do something which will save world.
}
Dziwi mnie, że nie ma odpowiedzi, która wspomniałaby o rozwiązaniu z RxJava2 . To jest naprawdę proste i zapewnia łatwy sposób na ustawienie timera w Androidzie.
Najpierw musisz skonfigurować zależność Gradle, jeśli jeszcze tego nie zrobiłeś:
implementation "io.reactivex.rxjava2:rxjava:2.x.y"
(wymienić x
i y
z aktualnym numerem wersji )
Ponieważ mamy tylko proste, BEZ POWTARZANIA ZADANIE , możemy użyć Completable
obiektu:
Completable.timer(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(() -> {
// Timer finished, do something...
});
W przypadku POWTARZANIA ZADANIA można użyć Observable
w podobny sposób:
Observable.interval(2, TimeUnit.SECONDS, Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(tick -> {
// called every 2 seconds, do something...
}, throwable -> {
// handle error
});
Schedulers.computation()
zapewnia, że nasz zegar działa na wątku w tle i .observeOn(AndroidSchedulers.mainThread())
oznacza, że kod uruchamiany po zakończeniu timera zostanie wykonany w głównym wątku.
Aby uniknąć niechcianych wycieków pamięci, należy anulować subskrypcję, gdy Aktywność / Fragment zostanie zniszczona.
Subscription
zwrócony przez .subscribe()
metodę w zmiennej, a następnie wywołać, subscription.unsubscribe()
gdy chcesz zatrzymać stoper.
Jest prostszym rozwiązaniem, działa dobrze w mojej aplikacji.
public class MyActivity extends Acitivity {
TextView myTextView;
boolean someCondition=true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
myTextView = (TextView) findViewById(R.id.refreshing_field);
//starting our task which update textview every 1000 ms
new RefreshTask().execute();
}
//class which updates our textview every second
class RefreshTask extends AsyncTask {
@Override
protected void onProgressUpdate(Object... values) {
super.onProgressUpdate(values);
String text = String.valueOf(System.currentTimeMillis());
myTextView.setText(text);
}
@Override
protected Object doInBackground(Object... params) {
while(someCondition) {
try {
//sleep for 1s in background...
Thread.sleep(1000);
//and update textview in ui thread
publishProgress();
} catch (InterruptedException e) {
e.printStackTrace();
};
return null;
}
}
}
Chcesz, aby aktualizacje interfejsu użytkownika miały miejsce w już istniejącym wątku interfejsu użytkownika.
Najlepszym sposobem jest użycie modułu obsługi, który korzysta z funkcji postDelayed, aby uruchomić Runnable po opóźnieniu (każde uruchomienie planuje następne); wyczyść połączenie zwrotne za pomocą removeCallbacks.
Patrzysz już we właściwe miejsce, więc spójrz na to jeszcze raz, być może wyjaśnij, dlaczego ta próbka kodu nie jest tym, czego chcesz. (Zobacz także identyczny artykuł na temat aktualizacji interfejsu użytkownika z timera ).
Oto prosty, niezawodny sposób ...
Umieść następujący kod w swojej aktywności, a metoda tick () będzie wywoływana co sekundę w wątku interfejsu użytkownika, gdy twoja aktywność będzie w stanie „wznowionym”. Oczywiście możesz zmienić metodę tick (), aby robić to, co chcesz, lub być nazywanym mniej lub bardziej często.
@Override
public void onPause() {
_handler = null;
super.onPause();
}
private Handler _handler;
@Override
public void onResume() {
super.onResume();
_handler = new Handler();
Runnable r = new Runnable() {
public void run() {
if (_handler == _h0) {
tick();
_handler.postDelayed(this, 1000);
}
}
private final Handler _h0 = _handler;
};
r.run();
}
private void tick() {
System.out.println("Tick " + System.currentTimeMillis());
}
Dla zainteresowanych kod „_h0 = _handler” jest niezbędny, aby uniknąć jednoczesnego działania dwóch timerów, jeśli aktywność zostanie wstrzymana i wznowiona w okresie tykania.
_h0
podejście, zamiast removeCallbacks
w onPause
, jak wszyscy inni?
Możesz także użyć do tego animatora:
int secondsToRun = 999;
ValueAnimator timer = ValueAnimator.ofInt(secondsToRun);
timer.setDuration(secondsToRun * 1000).setInterpolator(new LinearInterpolator());
timer.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
int elapsedSeconds = (int) animation.getAnimatedValue();
int minutes = elapsedSeconds / 60;
int seconds = elapsedSeconds % 60;
textView.setText(String.format("%d:%02d", minutes, seconds));
}
});
timer.start();
Musisz utworzyć wątek do obsługi pętli aktualizacji i użyć go do zaktualizowania obszaru tekstowego. Problem polega jednak na tym, że tylko główny wątek może tak naprawdę modyfikować interfejs użytkownika, więc wątek pętli aktualizacji musi zasygnalizować, że wątek główny wykona aktualizację. Odbywa się to za pomocą modułu obsługi.
Sprawdź ten link: http://developer.android.com/guide/topics/ui/dialogs.html# Kliknij sekcję „Przykład ProgressDialog z drugim wątkiem”. Jest to przykład tego, co musisz zrobić, z wyjątkiem okna dialogowego postępu zamiast pola tekstowego.
void method(boolean u,int max)
{
uu=u;
maxi=max;
if (uu==true)
{
CountDownTimer uy = new CountDownTimer(maxi, 1000)
{
public void onFinish()
{
text.setText("Finish");
}
@Override
public void onTick(long l) {
String currentTimeString=DateFormat.getTimeInstance().format(new Date());
text.setText(currentTimeString);
}
}.start();
}
else{text.setText("Stop ");
}
Jeśli ktoś jest zainteresowany, zacząłem bawić się tworzeniem standardowego obiektu do uruchomienia w wątku interfejsu użytkownika działań. Wygląda na to, że działa dobrze. Komentarze mile widziane. Chciałbym, aby to było dostępne w projektancie układu jako komponent do przeciągnięcia na działanie. Nie mogę uwierzyć, że coś takiego już nie istnieje.
package com.example.util.timer;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Activity;
public class ActivityTimer {
private Activity m_Activity;
private boolean m_Enabled;
private Timer m_Timer;
private long m_Delay;
private long m_Period;
private ActivityTimerListener m_Listener;
private ActivityTimer _self;
private boolean m_FireOnce;
public ActivityTimer() {
m_Delay = 0;
m_Period = 100;
m_Listener = null;
m_FireOnce = false;
_self = this;
}
public boolean isEnabled() {
return m_Enabled;
}
public void setEnabled(boolean enabled) {
if (m_Enabled == enabled)
return;
// Disable any existing timer before we enable a new one
Disable();
if (enabled) {
Enable();
}
}
private void Enable() {
if (m_Enabled)
return;
m_Enabled = true;
m_Timer = new Timer();
if (m_FireOnce) {
m_Timer.schedule(new TimerTask() {
@Override
public void run() {
OnTick();
}
}, m_Delay);
} else {
m_Timer.schedule(new TimerTask() {
@Override
public void run() {
OnTick();
}
}, m_Delay, m_Period);
}
}
private void Disable() {
if (!m_Enabled)
return;
m_Enabled = false;
if (m_Timer == null)
return;
m_Timer.cancel();
m_Timer.purge();
m_Timer = null;
}
private void OnTick() {
if (m_Activity != null && m_Listener != null) {
m_Activity.runOnUiThread(new Runnable() {
@Override
public void run() {
m_Listener.OnTimerTick(m_Activity, _self);
}
});
}
if (m_FireOnce)
Disable();
}
public long getDelay() {
return m_Delay;
}
public void setDelay(long delay) {
m_Delay = delay;
}
public long getPeriod() {
return m_Period;
}
public void setPeriod(long period) {
if (m_Period == period)
return;
m_Period = period;
}
public Activity getActivity() {
return m_Activity;
}
public void setActivity(Activity activity) {
if (m_Activity == activity)
return;
m_Activity = activity;
}
public ActivityTimerListener getActionListener() {
return m_Listener;
}
public void setActionListener(ActivityTimerListener listener) {
m_Listener = listener;
}
public void start() {
if (m_Enabled)
return;
Enable();
}
public boolean isFireOnlyOnce() {
return m_FireOnce;
}
public void setFireOnlyOnce(boolean fireOnce) {
m_FireOnce = fireOnce;
}
}
W tym działaniu mam onStart:
@Override
protected void onStart() {
super.onStart();
m_Timer = new ActivityTimer();
m_Timer.setFireOnlyOnce(true);
m_Timer.setActivity(this);
m_Timer.setActionListener(this);
m_Timer.setDelay(3000);
m_Timer.start();
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
CheckBox optSingleShot;
Button btnStart, btnCancel;
TextView textCounter;
Timer timer;
MyTimerTask myTimerTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
optSingleShot = (CheckBox)findViewById(R.id.singleshot);
btnStart = (Button)findViewById(R.id.start);
btnCancel = (Button)findViewById(R.id.cancel);
textCounter = (TextView)findViewById(R.id.counter);
btnStart.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
if(timer != null){
timer.cancel();
}
//re-schedule timer here
//otherwise, IllegalStateException of
//"TimerTask is scheduled already"
//will be thrown
timer = new Timer();
myTimerTask = new MyTimerTask();
if(optSingleShot.isChecked()){
//singleshot delay 1000 ms
timer.schedule(myTimerTask, 1000);
}else{
//delay 1000ms, repeat in 5000ms
timer.schedule(myTimerTask, 1000, 5000);
}
}});
btnCancel.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if (timer!=null){
timer.cancel();
timer = null;
}
}
});
}
class MyTimerTask extends TimerTask {
@Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
final String strDate = simpleDateFormat.format(calendar.getTime());
runOnUiThread(new Runnable(){
@Override
public void run() {
textCounter.setText(strDate);
}});
}
}
}
.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:autoLink="web"
android:text="http://android-er.blogspot.com/"
android:textStyle="bold" />
<CheckBox
android:id="@+id/singleshot"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Single Shot"/>
Jeśli masz już czas delta.
public class Timer {
private float lastFrameChanged;
private float frameDuration;
private Runnable r;
public Timer(float frameDuration, Runnable r) {
this.frameDuration = frameDuration;
this.lastFrameChanged = 0;
this.r = r;
}
public void update(float dt) {
lastFrameChanged += dt;
if (lastFrameChanged > frameDuration) {
lastFrameChanged = 0;
r.run();
}
}
}
I abstrakcyjny Timer odszedł i uczynił z niego osobną klasę:
Timer.java
import android.os.Handler;
public class Timer {
IAction action;
Handler timerHandler = new Handler();
int delayMS = 1000;
public Timer(IAction action, int delayMS) {
this.action = action;
this.delayMS = delayMS;
}
public Timer(IAction action) {
this(action, 1000);
}
public Timer() {
this(null);
}
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
if (action != null)
action.Task();
timerHandler.postDelayed(this, delayMS);
}
};
public void start() {
timerHandler.postDelayed(timerRunnable, 0);
}
public void stop() {
timerHandler.removeCallbacks(timerRunnable);
}
}
I wyodrębnij główną akcję z Timer
klasy jako
IAction.java
public interface IAction {
void Task();
}
I użyłem tego tak:
MainActivity.java
public class MainActivity extends Activity implements IAction{
...
Timer timerClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
timerClass = new Timer(this,1000);
timerClass.start();
...
}
...
int i = 1;
@Override
public void Task() {
runOnUiThread(new Runnable() {
@Override
public void run() {
timer.setText(i + "");
i++;
}
});
}
...
}
Mam nadzieję, że to pomaga 😊👌
Używam w ten sposób:
String[] array={
"man","for","think"
}; int j;
następnie poniżej onCreate
TextView t = findViewById(R.id.textView);
new CountDownTimer(5000,1000) {
@Override
public void onTick(long millisUntilFinished) {}
@Override
public void onFinish() {
t.setText("I "+array[j] +" You");
j++;
if(j== array.length-1) j=0;
start();
}
}.start();
to prosty sposób na rozwiązanie tego problemu.
Dla tych, którzy nie mogą polegać na Chronometrze , stworzyłem klasę użyteczności na podstawie jednej z sugestii:
public class TimerTextHelper implements Runnable {
private final Handler handler = new Handler();
private final TextView textView;
private volatile long startTime;
private volatile long elapsedTime;
public TimerTextHelper(TextView textView) {
this.textView = textView;
}
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int) (millis / 1000);
int minutes = seconds / 60;
seconds = seconds % 60;
textView.setText(String.format("%d:%02d", minutes, seconds));
if (elapsedTime == -1) {
handler.postDelayed(this, 500);
}
}
public void start() {
this.startTime = System.currentTimeMillis();
this.elapsedTime = -1;
handler.post(this);
}
public void stop() {
this.elapsedTime = System.currentTimeMillis() - startTime;
handler.removeCallbacks(this);
}
public long getElapsedTime() {
return elapsedTime;
}
}
użyć… po prostu wykonaj:
TimerTextHelper timerTextHelper = new TimerTextHelper(textView);
timerTextHelper.start();
.....
timerTextHelper.stop();
long elapsedTime = timerTextHelper.getElapsedTime();