타이머가 작동하면서 다른 코드도 동작해야 하기 때문에 타이머는 비동기 처리 방식으로 구현해야한다.
2021.03.30 - [코틀린] - [Kotlin] 코틀린 비동기 처리 (코루틴)
[Kotlin] 코틀린 비동기 처리 (코루틴)
여러개의 구문을 동시에 실행하고 싶다면 코루틴을 사용해야한다. 코루틴의 Scope 코루틴은 제어범위 및 실행범위를 지정할 수 있다. GlobalScope : 프로그램 어디서나 동작,제어가 가능한 기본 범위
hanyeop.tistory.com
코루틴에 대한 간략한 글은 이 곳에 정리하였다.
MVVM 패턴을 기반으로 작성할 것이다.
2021.04.26 - [안드로이드/기본] - [Android] 안드로이드 ViewModel, LiveData (+DataBinding)
[Android] 안드로이드 ViewModel, LiveData (+DataBinding)
2021.04.19 - [안드로이드/기본] - [Android] 안드로이드 AAC & MVVM [Android] 안드로이드 AAC & MVVM 액티비티, 프래그먼트에 너무 많은 코드를 넣게 되면 점점 무거워져 다루기 힘들어지게 된다. 앱이 카메라.
hanyeop.tistory.com
사용해보기
dependencies 추가
def lifecycle_version = "2.3.0"
// ViewModel - 라이프 사이클
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData - 데이터의 변경 사항을 알 수 있음
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// 코루틴
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
뷰모델과 라이브데이터, 코루틴을 사용할 것이기 때문에 dependencies 에 추가해준다.
DataBinding 추가
// 데이터바인딩
buildFeatures {
dataBinding true
}
데이터바인딩을 사용할 것이기 때문에 bulid.gradle (Module) 의 android 에 추가해준다.
레이아웃
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="org.techtown.coroutineTest.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/timer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{Integer.toString(viewModel.timerCount)}"
app:layout_constraintBottom_toBottomOf="parent"
android:textSize="30sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.226" />
<Button
android:id="@+id/startButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="36dp"
android:text="타이머 시작"
android:textSize="19sp"
android:onClick="@{() -> viewModel.timerStart()}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/timer" />
<Button
android:id="@+id/pauseButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="타이머 정지"
android:textSize="19sp"
android:onClick="@{() -> viewModel.timerStop()}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/startButton" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
타이머 텍스트뷰와 타이머를 시작하고 정지할 수 있는 버튼을 추가한다.
타이머는 뷰모델에 있는 라이브데이터에 바인딩해주고, 버튼도 각각 메소드에 바인딩해준다.
뷰모델
class MainViewModel : ViewModel() {
private val _timerCount = MutableLiveData<Int>()
private lateinit var a : Job
// Getter
val timerCount : LiveData<Int>
get() = _timerCount
init{
_timerCount.value = 5
}
fun timerStart(){
if(::a.isInitialized) a.cancel()
_timerCount.value = 5
a = viewModelScope.launch {
while(_timerCount.value!! > 0) {
_timerCount.value = _timerCount.value!!.minus(1)
delay(1000L)
}
}
}
fun timerStop(){
if(::a.isInitialized) a.cancel()
}
}
스타트 클릭시
1초당 타이머를 1씩 감소시킨다.
viewModelScope는 해당 ViewModel이 onClear시 같이 취소된다.
메인액티비티
class MainActivity : AppCompatActivity() {
lateinit var mainViewModel: MainViewModel
lateinit var binding : ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
binding.viewModel = mainViewModel
binding.lifecycleOwner = this
}
}
뷰모델을 연결하여 옵저빙한다.
감소된 타이머값이 UI에 실시간으로 반영된다.
github.com/HanYeop/AndroidStudio-Practice/tree/master/Coroutine_Test
HanYeop/AndroidStudio-Practice
안드로이드 학습 내용 저장소. Contribute to HanYeop/AndroidStudio-Practice development by creating an account on GitHub.
github.com