• Android(kotlin)JetPack系列学习——3.LiveData(含源码)


    1. LiveData简介

    LiveData是一个可观察的数据持有者类(响应式编程),它也是有生命周期感知的;LiveDate最重要的是它了解其观察者的生命周期, 如Activity和Fragment. 这就意味着实时数据仅更新于处于活动生命周期状态的应用程序组件,如Activity和Fragment。 因此,当LiveDate发生变化时,UI会收到通知,然后UI根据新数据重新绘制自己。

    2. LiveDate的优势

    • UI与数据状态匹配: LiveData遵循观察者模式,在活动状态下,每当组件的数据发生更改时, 特定组件都会匹配该状态而不会失败。所以,我们不需要在每次应用数据更改时更新UI, 因为Observer会处理这些
    • 提高代码的稳定性
      代码稳定性在整个应用程序组件生命周期中增加:
      1)活动停止时不会发生崩溃。如果应用程序组件处于非活动状态,则这些更改不受影响。因此,您在更新数据时无需担心应用程序组件的生命周期。对于后台堆栈中的活动,它不会接收任何LiveData 事件
      2)内存泄漏将减少,因为不需要的事件/分配会自动处理
      3)取消订阅任何观察者时无需担心
      4)在配置/屏幕方向更改期间,无需更新最新数据
    • 无需手动处理生命周期:LiveData 知道视图的生命周期。因此,Ul组件只是观察相关数据,不会停止或恢复观察。LiveData在观察时会自动管理所有这些更改。
    • 始终与最新数据保持同步
    • 共享资源: 像单例模式一样,我们也可以扩展我们的LiveData对象来包装系统服务,以便它们可以在我们的应用程序中共享。一旦LiveData 对象连接到系统服务,任何需要资源的观察者都可以轻松地观看LiveData 对象。

    3. 不适用LiveData的情况

    • 需要在数据上使用大量运算
    • 信息不与UI交互
    • 有一次性异步操作

    4. 简单使用

    Step1: 引入依赖

    plugins {
        id 'com.android.application'
        id 'org.jetbrains.kotlin.android'
        id 'kotlin-kapt'
    }
    
    android {
        compileSdk 32
    
        defaultConfig {
            applicationId "com.exam.livedata"
            minSdk 21
            targetSdk 32
            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{
            viewBinding = true
            dataBinding = true
        }
    
    }
    
    dependencies {
    
        implementation 'androidx.core:core-ktx:1.7.0'
        implementation 'androidx.appcompat:appcompat:1.3.0'
        implementation 'com.google.android.material:material:1.4.0'
        implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
        testImplementation 'junit:junit:4.13.2'
        androidTestImplementation 'androidx.test.ext:junit:1.1.3'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
    
        // 监听整个应用程序的生命周期
        implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
        implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
        implementation 'androidx.lifecycle:lifecycle-process:2.5.1'
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55

    Step2: 使用

    class MainActivity : AppCompatActivity() {
    
        private lateinit var binding: ActivityMainBinding
        private val testLiveData = MutableLiveData<String>()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            setContentView(binding.root)
    
            // 发送数据
            testLiveData.observe(this){
                binding.tvText.text = it
            }
    
            binding.btnSend.setOnClickListener {
                testLiveData.value = "这是发送过来的数据"
                
            }
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    需要注意的是:

    (1)liveData.value=true //liveData.setValue//这个方法必须要在主线程中调用
    (2)liveData.postValue=true //这个方法可以在主线程中调用,也可以在子线程中调用

    5. 使用map进行字符转换

    如果我们保存的数据类型是int型,而需要的是String型,则可以通过Transformations.map()对LiveData进行字符转换,具体如下:

    class LiveDataForMapActivity2 : AppCompatActivity() {
    
        private val testLiveData = MutableLiveData<Int>()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_live_data_for_map2)
    
            // 将livedata中的int型转换为String型
            val liveMap = Transformations.map(testLiveData){
                // 将要转换的String型数据
                "livedata发送过来的数据是 ——> $it"
            }
    
            liveMap.observe(this){
                // 此时livedata中传来的数据就是String型了,直接在这里使用数据即可
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    以下全部代码如下:
    JetPackStudyDemo全部代码,欢迎star

  • 相关阅读:
    数据结构与算法之LeetCode-剑指 Offer II 091. 粉刷房子-动态规划-DP
    DASK==python并行计算
    spinning
    tomcat必要的配置
    商城秒杀系统总结(Java)
    Helm基础知识
    深度强化学习预训练,在线、离线
    servlet
    【MetaGPT】配置教程
    一文搞懂 SAE 日志采集架构
  • 原文地址:https://blog.csdn.net/qq_41915623/article/details/127600781