1. CountDownTimer를 활용한 타이머(Timer) 구현
1.1 화면 UI를 위한 레이아웃 리소스
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="60 초"
android:textAlignment="center"
android:textSize= "100dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="clickHandler"
android:text="Start" />
<Button
android:id="@+id/btnReset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="clickHandler"
android:text="Reset" />
</LinearLayout>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
▼ 타이머의 시간 경과를 표시하기 위한 TextView와 타이머 시작을 위한 Button 한 개와 타이머를 Reset 하기 위한 Button 한 개를 배치한 형태입니다. 포스팅 뒤에 나오는 Timer/TimerTask 구현예제도 동일한 레이아웃 리소스를 사용합니다.
1.2 CountDownTimer 상속받는 MyTimer 클래스 구현
class MyTimer extends CountDownTimer
{
public MyTimer(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
@Override
public void onTick(long millisUntilFinished) {
textView.setText(millisUntilFinished/1000 + " 초");
}
@Override
public void onFinish() {
textView.setText("0 초");
}
}
▼ CountDownTimer 클래스를 상속받는 MyTimer 클래스입니다. 생성자 함수로 첫 번째 인자로 타이머 동작하는 총 시간으로 밀리세컨트(ms) 단위로 넘어옵니다. 두 번재 인자는 카운트다운 되는 시간을 의미합니다. CountDownTimer는 추상 클래스로 onTick() 함수와 onFinish() 함수를 반드시 오버라이딩 합니다. 첫 번째 onTick() 함수는 생성자 인수 countDownInterval로 지정된 시간 간격마다 호출되는 함수입니다. 함수에 넘어오는 인자로는 현재 타이머의 남은 시간이 넘어옵니다. 두 번째로 onFinish() 함수는 타이머가 끝났을 때 호출되는 함수입니다.
1.3 MainActivity 클래스
public class MainActivity extends AppCompatActivity {
TextView textView;
MyTimer myTimer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView2);
myTimer = new MyTimer(60000, 1000);
}
public void clickHandler(View view)
{
switch(view.getId())
{
case R.id.btnStart:
myTimer.start();
break;
case R.id.btnReset :
myTimer.cancel();
textView.setText("60 초");
break;
}
}
▼ onCreate() 함수에서는 앞서 정의한 MyTimer 클래스의 객체를 생성합니다. 인자 정보는 타이머의 총 시간으로 60초로 지정하였으며, 두 번째 인자는 onTick() 함수가 호출될 시간 간격으로 1초를 넘겨줍니다. clickHandler() 함수에서는 버튼 두 개에 대한 이벤트 처리가 구현되어 있습니다. Start 버튼을 클릭했을때는 MyTimer의 start() 함수를 통해 타이머를 시작하고 Reset 버튼을 클릭했을 때는 cancle() 함수를 통해 타이머를 취소시킵니다.
2. Timer와 TimerTask를 통해 타이머(Timer) 구현하기
package com.springsthursday.timerforblog2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends AppCompatActivity {
TextView textView;
TimerTask timerTask;
Timer timer = new Timer();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView2);
}
@Override
protected void onDestroy()
{
timer.cancel();
super.onDestroy();
}
public void clickHandler(View view)
{
switch(view.getId())
{
case R.id.btnStart:
startTimerTask();
break;
case R.id.btnReset :
stopTimerTask();
break;
}
}
private void startTimerTask()
{
stopTimerTask();
timerTask = new TimerTask()
{
int count = 60;
@Override
public void run()
{
count--;
textView.post(new Runnable() {
@Override
public void run() {
textView.setText(count + " 초");
}
});
}
};
timer.schedule(timerTask,0 ,1000);
}
private void stopTimerTask()
{
if(timerTask != null)
{
textView.setText("60 초");
timerTask.cancel();
timerTask = null;
}
}
}
▼ 주기적으로 처리해야 할 작업을 구현해야 한다면 TimerTask 객체를 생성하여 run() 함수를 오버라이딩 하여 구현하면 됩니다. 해당 예제에서는 Start 버튼을 클릭하였을 때 startTimeTask() 함수를 호출하고 있습니다.
해당 함수에서는 run() 함수를 오버라이딩한 TimerTask 객체를 생성하여 Timer의 schedule() 함수를 통해서 구현 된 TimerTask를 Timer에 등록합니다. 나머지 두 번째 인자는 타이머 시작을 몇초 뒤 실행할 것인지를 지정하고 세 번째 인자는 시간 간격으로 몇초 간격으로 TimerTask의 구현내용을 실행할지를 지정합니다.