Более эффективный подход для кода секундомера Android?
Я новичок в разработке приложений для Android, поэтому я знаю, что, возможно, все усложняю.
Приведенный ниже код работает как положено (через много часов!!!), но мне интересно, правильно ли я выполняю реализацию двух потоков? Как я уже сказал, это работает, по крайней мере, но я не уверен, что все это необходимо.
PS: Бонусные баллы за то, что я показал формулу для преобразования сантисекунд в ч: м: с: с, чтобы мне не пришлось использовать то ужасное решение для длины строки, которое я нашел, лол! [РЕДАКТИРОВАТЬ... см. Ниже, я нашел ответ на эту часть]
package com.test.advancedtimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
String time; //Clock's combined time
String elapsedTime; //Stopwatch elapsed time
int stopwatchHour = 0;
int stopwatchMin = 0;
int stopwatchSec = 0;
int stopwatchCentiSec = 0;
int elapsedSeconds = 0;
int elapsedCentiseconds = 0; //cumulative Centiseconds elapsed since starting countdown
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
updateTime();
}
//First timer that updates the clock display once every second
public void updateTime() {
Timer clockTimer = new Timer();
clockTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
getTime();
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView timeTextView = (TextView) findViewById(R.id.time_display);
timeTextView.setText(getTime());
}
});
}
}, 0, 1000);
}
//Accesses system time and concatenates it into 'time' String, then returns it.
public String getTime() {
Calendar cal = new GregorianCalendar();
int hour = cal.get(Calendar.HOUR);
int min = cal.get(Calendar.MINUTE);
int sec = cal.get(Calendar.SECOND);
int AM_PM = cal.get(Calendar.AM_PM);
String AMorPM = "";
// Establishes two-digit format for clock time
time = (hour < 10 ? "0" : "") + hour + ":";
time += (min < 10 ? "0" : "") + min + ":";
time += (sec < 10 ? "0" : "") + sec;
if (AM_PM == 0) {
AMorPM = "AM";
} else if (AM_PM == 1) {
AMorPM = "PM";
}
time += " " + AMorPM;
return time;
}
// Second timer that triggers the stopwatch to increment by centiseconds (1/10th seconds)
public void startTimer(View view) {
Timer stopwatchTimer = new Timer();
stopwatchTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView timerTextView = (TextView) findViewById(R.id.runningTimer);
timerTextView.setText(stopwatch());
}
});
}
}, 0, 10);
}
// Returns the combined string for the stopwatch, counting in tenths of seconds.
public String stopwatch() {
elapsedSeconds = elapsedCentiseconds / 100; //Conversion to enable use of same formula above
stopwatchHour = elapsedSeconds / 3600;
stopwatchMin = (elapsedSeconds % 3600) / 60;
stopwatchSec = elapsedSeconds % 60;
//Formats stopwatch to two digits per time unit.
elapsedTime = (stopwatchHour < 10 ? "0" : "") + stopwatchHour + ":";
elapsedTime += (stopwatchMin < 10 ? "0" : "") + stopwatchMin + ":";
elapsedTime += (stopwatchSec < 10 ? "0" : "") + stopwatchSec + ":";
//Grabs last two digits of total centiseconds for centisecond component.
String centiSeconds = String.valueOf(elapsedCentiseconds);
if (centiSeconds.length() >1) {
elapsedTime += centiSeconds.charAt(centiSeconds.length() - 2);
elapsedTime += centiSeconds.charAt(centiSeconds.length() - 1);
} else {
elapsedTime += "0" + centiSeconds.charAt(centiSeconds.length() - 1);
}
elapsedCentiseconds++;
return elapsedTime;
}
}
РЕДАКТИРОВАТЬ: я, наконец, получил математику, чтобы работать на преобразование из десятых секунд (на что я переключился, потому что цифра в сотые секунды двигался слишком быстро, чтобы быть полезным):
// Returns the combined string for the stopwatch, counting in tenths of seconds.
public String stopwatch() {
//elapsedSeconds = elapsedDeciseconds / 10; //Conversion to enable use of same formula above
stopwatchHour = (elapsedDeciseconds % 2160000) / 36000;
stopwatchMin = (elapsedDeciseconds % 36000) / 600;
stopwatchSec = (elapsedDeciseconds % 600) / 10;
stopwatchDeciseconds = elapsedDeciseconds % 10;
//Formats stopwatch to two digits per time unit.
elapsedTime = (stopwatchHour < 10 ? "0" : "") + stopwatchHour + ":";
elapsedTime += (stopwatchMin < 10 ? "0" : "") + stopwatchMin + ":";
elapsedTime += (stopwatchSec < 10 ? "0" : "") + stopwatchSec + ":";
elapsedTime += stopwatchDeciseconds;
elapsedDeciseconds++;
return elapsedTime;
}
1 ответ
public long startTime = 0;
public void startTimer(View view) {
Timer stopwatchTimer = new Timer();
startTime = System.currentTimeMillis();
stopwatchTimer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
@Override
public void run() {
TextView timerTextView = (TextView) findViewById(R.id.runningTimer);
timerTextView.setText(stopwatch());
}
});
}
}, 0, 10);
}
// Returns the combined string for the stopwatch, counting in tenths of seconds.
public String stopwatch() {
long nowTime = System.currentTimeMillis();
long cast = nowTime - startTime;
Date date = new Date(cast);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss.S");
return simpleDateFormat.format(date);
}