본문 바로가기

Android/MVVM

Live Data

  • Android LiveData는 수명주기를 인식하고 관찰 가능한 데이터 홀더 클래스입니다.
  • 이름에서 알 수 있듯이 라이브 데이터를 가져 오는 데 사용합니다.
  • 즉, 데이터 소스에서 실시간 업데이트를 가져옵니다.
  • LiveData 라이브러리는 배우고 사용하기가 매우 쉽습니다. 당신은 그것을 즐길 것입니다.

LiveData는 어디에서 생성 / 생성합니까?

  • 우리는 일반적으로 ViewModel 클래스 내에서 LiveData를 정의합니다.
  • 또한 Room 및 Retrofit과 같은 지원 라이브러리를 통해 LiveData 형식으로 데이터를 직접 가져올 수 있습니다.

어디에서 LiveData를 관찰합니까?

  • LiveData는 수명주기를 인식하는 관찰 가능한 데이터 홀더 클래스입니다.
  • 그러나 Android에는 수명주기가있는 3 개의 앱 구성 요소 만 있습니다. 액티비티, 프래그먼트 및 서비스.
  • 따라서 활동, 조각 및 서비스를 형성하여 LiveData를 관찰 할 수 있습니다.

RxJava 대 LiveData.

  • RxJava는 라이프 사이클 인식 구성 요소가 아닙니다.
  • 따라서 액티비티, 프래그컨트 또는 서비스가 비활성화 될 때 데이터 스트림이 꺼지지 않습니다.
  • 그 결과 메모리 누수 또는 충돌이 발생할 수 있습니다.
  • 따라서 수동으로 처리하는 코드를 작성해야합니다.
  • 그러나 반면에 Android LiveData는 수명주기 상태 변경을 인식합니다.
  • 그리고 관련 라이프 사이클이 파괴되면 스스로를 정리합니다.

이 자습서에서는 ViewModel 자습서에서 만든 앱을 사용합니다.

이 github 링크에서 해당 코드 프로젝트를 다운로드 할 수 있습니다.

>>이 튜토리얼의 시작 코드 프로젝트를 다운로드하기위한 GITHUB 링크

 

자, 우리가 가지고있는 코드를 연구하는 것으로 시작합시다.

MainActivityViewModel.kt

 

class MainActivityViewModel(startingCount : Int) : ViewModel() {
 
    private var count = startingCount
 
    fun getCurrentCount():Int{
        return count
    }
 
    fun getUpdatedCount():Int{
        return ++count
    }
}

뷰 모델 클래스에서 현재 클릭 수 값을 보유하기 위해 "count"라는 변수를 정의했습니다

그 후 카운트 값을 반환하는 "getCurrentCount"라는 함수를 생성했습니다

또한 "getUpdatedCount"라는 또 다른 함수를 만들었습니다. 이 함수는 카운트 값을 1 씩 증가시키고 새 값을 반환합니다.

 

 

MainActivity.kt

class MainActivity : AppCompatActivity() {
    
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: MainActivityViewModel
    private lateinit var viewModelFactory: MainActivityViewModelFactory
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        
        viewModelFactory = MainActivityViewModelFactory(125)
        viewModel = ViewModelProvider(this, viewModelFactory).get(MainActivityViewModel::class.java)
        
        binding.countText.text = viewModel.getCurrentCount().toString()
        
        binding.button.setOnClickListener {
            
            binding.countText.text = viewModel.getUpdatedCount().toString()
            
        }
    }
}

그런 다음 Main Activity의 onCreate () 함수에서 "getCurrentCount ()"함수를 호출하여 "count"값을 가져 오는 코드를 작성했습니다

사용자가 버튼을 클릭 할 때마다 현재 클릭 수 값은 1 씩 증가해야합니다. 그리고 새로 업데이트 된 값이 TextView에 표시되어야합니다. 그래서 우리는 버튼의 클릭 리스너를 구현하고 해당 작업에 대한 코드를 작성했습니다

그러나 위의 코드를 작성하는 더 나은 "최첨단"방법이 있습니다.
Android LiveData를 사용하면 액티비티 (또는 프래그먼트)에서 뷰 모델의 데이터를 관찰하는 코드를 작성할 수 있습니다.
가장 중요한 것은 뷰 모델의 데이터가 변경되면 액티비티 (또는 프래그먼트)의 해당 값이 실시간 업데이트를 받게된다는 것입니다.

 

 

Required Dependencies

먼저 앱 레벨 build.gradle 파일에 LiveData 종속성을 추가해야합니다.

def lifecycle_version = "2.3.0"
 
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"

이것이 새 종속성을 추가 한 후 앱 수준 build.gradle 파일이 표시되는 방식입니다.

build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
    id 'kotlin-kapt'
}
 
android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"
 
    defaultConfig {
        applicationId "com.anushka.livedatademo_final1"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"
 
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
 
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures{
        dataBinding = true
    }
}
 
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.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}

그런 다음 MainActivityViewModel.kt를 엽니 다. 그리고 "count"변수를 Int 유형  MutableLiveData  변경합니다 . 또한 "private"한정자를 제거합니다. MainActivity에서이를 관찰 할 것입니다.

var count = MutableLiveData<Int>()

 

MutableLiveData Vs LiveData

  • MutableLiveData 클래스는 LiveData 클래스의 하위 클래스입니다. 즉, 부모 LiveData 클래스를 확장하여 MutableLiveData 자식 클래스를 생성 한 것입니다.
  • MutableLiveData 인스턴스는 LiveData 인스턴스가 할 수있는 모든 것을 할 수 있습니다.
  • LiveData 개체의 데이터는 읽기만 가능합니다. 이러한 값은 업데이트 할 수 없습니다.
  • 그러나 다른 한편으로 Mutable LiveData 객체를 사용하면 값을 변경 (업데이트) 할 수 있습니다.
  • 그래서 우리 자신의 라이브 데이터 (주로 ViewModels에서)를 생성 할 때, 우리는 그것들을 MutableLiveData로 정의합니다.
  • 그러나 Room 및 Retrofit과 같은 다른 라이브러리에서 라이브 데이터를 가져올 때 LiveData로 가져옵니다.
  • 이 두 형식간에 값을 쉽게 전송할 수 있습니다.
  • 여기에서이 MainActivityViewModel에서 항상 "count"값을 업데이트해야합니다. 따라서 MutableLiveData 여야합니다.

 

LiveData의 값을 업데이트하는 방법은 무엇입니까?

코드로 돌아 갑시다.

이제이 "count"변수는 MutableLiveData입니다. 그래서, 우리는 그것에 startingTotal 변수를 할당 할 수 없습니다. 우리 는 그것  value 속성 을 가져 와서 value 속성 에 시작 합계를 할당해야합니다. init 블록 안에서해야합니다.

init {
        count.value = startingCount
    }

"count"의 값을 관찰 할 것이므로 getCurrentCount functon (method)을 수동으로 생성 할 필요가 없습니다. 그럼 삭제하겠습니다.

그리고 "count"의 값을 관찰 할 것이므로 아무것도 반환하는 데 setCurrentCount 함수가 필요하지 않습니다.

따라서 함수의 이름을 "updateCount"로 변경하겠습니다.

그런 다음이 코드 줄을 추가하여 각 함수 호출에 대해 값을 하나씩 늘립니다.

 

count.value = (count.value)?.plus(1)

 

MainActivityViewModel.kt

class MainActivityViewModel(startingCount : Int) : ViewModel() {
 
    var count = MutableLiveData<Int>()
 
 
    init {
        count.value = startingCount
    }
    
    fun updateCount(){
        count.value = (count.value)?.plus(1)
    }
}

 

LiveData를 관찰하는 방법?

Now, let’s switch back to MainActivity and make some changes to observe the “count”.

viewModel.count.observe(this, Observer {
            binding.countText.text = it.toString()
        })

위의 코드에서 "it"은 라이브 데이터의 값을 나타냅니다. 이 경우 "it"은 Int 값입니다. 따라서 toString ()을 사용하여 문자열로 변환해야합니다.

그런 다음 버튼의 클릭 리스너 내에서해야 할 일은 viewmodel의 updataCount 함수를 호출하는 것입니다.

      binding.button.setOnClickListener {
           viewModel.updateCount()
        }

다음은 LiveData 용으로 수정 된 MainActivity.kt입니다.

 

MainActivity.kt

class MainActivity : AppCompatActivity() {
 
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: MainActivityViewModel
    private lateinit var viewModelFactory: MainActivityViewModelFactory
 
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
 
        viewModelFactory = MainActivityViewModelFactory(125)
        viewModel = ViewModelProvider(this, viewModelFactory).get(MainActivityViewModel::class.java)
 
        viewModel.count.observe(this, Observer {
            binding.countText.text = it.toString()
        })
 
        binding.button.setOnClickListener {
           viewModel.updateCount()
        }
    }
}

이제 앱을 실행하면 예상 한 결과를 얻을 수 있습니다.

 

Encapsulation

MainActivityViewModel 클래스에서 "count"를 공용 변수로 정의했습니다. 

var count = MutableLiveData <Int> ( )

 

이것은 소프트웨어 엔지니어링 모범 사례가 아닙니다. 원래 변수에 대한 공개 액세스를 허용하면 전문가 수준 응용 프로그램에서 보안 문제가 발생할 수 있습니다.

그러나 w는 Kotlin 지원 속성을 사용하여 이러한 변수에 대한 액세스를 매우 쉽게 제한 할 수 있습니다.

그 방법을 보여 드리겠습니다.

 

먼저 count 변수를 private으로 만듭니다.

private var count = MutableLiveData <Int> ( )

 

둘째, 공유 목적으로 공개 LiveData를 정의한 다음 Kotlin의 지원 속성을 사용하여 해당 라이브 데이터의 값으로 "count"값을 가져올 수 있습니다.

private var count = MutableLiveData<Int>()
    val countValue : LiveData<Int>
    get() = count

이제 MainActivity.kt로 돌아갑니다. 그리고 "count"대신 "countValue"를 관찰하도록 코드를 변경합니다. (countValue에서 개수 바꾸기)

viewModel.countValue.observe(this, Observer {
            binding.countText.text = it.toString()
        })

그리고 이것들은 MainActivityViewModel과 MainActivity의 최종 코드입니다.

 

MainActivityViewModel.kt

class MainActivityViewModel(startingCount : Int) : ViewModel() {
 
    private var count = MutableLiveData<Int>()
    val countValue : LiveData<Int>
    get() = count
    
    init {
        count.value = startingCount
    }
 
    fun updateCount(){
        count.value = (count.value)?.plus(1)
    }
}

MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
 
        viewModelFactory = MainActivityViewModelFactory(125)
        viewModel = ViewModelProvider(this, viewModelFactory).get(MainActivityViewModel::class.java)
 
        viewModel.countValue.observe(this, Observer {
            binding.countText.text = it.toString()
        })
 
        binding.button.setOnClickListener {
           viewModel.updateCount()
        }
    }
}

 


원문

https://appdevnotes.com/android-livedata-tutorial-for-beginners-in-kotlin/

반응형

'Android > MVVM' 카테고리의 다른 글

Data Binding with LiveData.  (0) 2021.05.20
Two Way Data Binding vs One Way Data Binding  (0) 2021.05.20
안드로이드 뷰모델  (0) 2021.05.20
안드로이드 데이터 바인딩  (0) 2021.05.20
02. MVVM 적용 샘플 #01  (0) 2021.03.31