Lifecycle 和 ViewModel
概念 主要职责
Lifecycle 管理组件的生命周期状态,比如 Activity/Fragment 当前是创建、启动、暂停、销毁
ViewModel 保存和管理界面相关数据,让数据在配置变化时不丢失,比如屏幕旋转

简单说:

Lifecycle 管“界面活没活着”
ViewModel 管“界面需要的数据”


1. Lifecycle 是什么?

Lifecycle 是 Android Jetpack 提供的生命周期管理组件。

它用来感知:

  • Activity 是否创建了
  • Fragment 是否可见
  • 页面是否进入后台
  • 页面是否销毁

常见生命周期状态:

INITIALIZED
CREATED
STARTED
RESUMED
DESTROYED

常见生命周期事件:

ON_CREATE
ON_START
ON_RESUME
ON_PAUSE
ON_STOP
ON_DESTROY

Activity 常见生命周期方法

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化界面、ViewModel、监听器
    }

    override fun onStart() {
        super.onStart()
        // 页面开始可见
    }

    override fun onResume() {
        super.onResume()
        // 页面可以交互
    }

    override fun onPause() {
        super.onPause()
        // 页面失去焦点,例如弹窗、跳转
    }

    override fun onStop() {
        super.onStop()
        // 页面不可见
    }

    override fun onDestroy() {
        super.onDestroy()
        // 页面销毁,释放资源
    }
}

Fragment 常见生命周期方法

class HomeFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化非 View 相关数据
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 创建 Fragment 的 View
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // View 创建完成,初始化控件、观察数据
    }

    override fun onDestroyView() {
        super.onDestroyView()
        // View 被销毁,清理 binding 等
    }

    override fun onDestroy() {
        super.onDestroy()
        // Fragment 被销毁
    }
}

2. Lifecycle 常用方式

方式一:lifecycleScope

在 Activity/Fragment 中启动协程,并自动跟随生命周期取消。

lifecycleScope.launch {
    // 执行协程任务
}

例如:

lifecycleScope.launch {
    delay(1000)
    textView.text = "加载完成"
}

当 Activity/Fragment 销毁时,这个协程会自动取消。


方式二:repeatOnLifecycle

这是现在非常常用的方式,尤其配合 Flow。

lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            // 更新 UI
        }
    }
}

含义是:

当页面至少处于 STARTED 状态时收集数据;
页面 STOP 后自动停止收集;
页面重新 START 后重新收集。

这比直接 collect 更安全。


方式三:LifecycleObserver

可以写一个类来观察生命周期。

class MyObserver : DefaultLifecycleObserver {

    override fun onStart(owner: LifecycleOwner) {
        println("页面开始可见")
    }

    override fun onStop(owner: LifecycleOwner) {
        println("页面不可见")
    }
}

使用:

lifecycle.addObserver(MyObserver())

适合封装某些需要感知生命周期的组件,比如定位、播放器、传感器等。


3. ViewModel 是什么?

ViewModel 用来保存和管理 UI 数据。

它的特点是:

  • 不直接持有 View
  • 不应该持有 Activity、Fragment 的引用
  • 屏幕旋转时不会被重新创建
  • Activity/Fragment 销毁时才会真正清除

例如:页面上展示用户信息、列表数据、加载状态,这些就适合放在 ViewModel 里。


ViewModel 示例

class MainViewModel : ViewModel() {

    private val _name = MutableStateFlow("张三")
    val name: StateFlow<String> = _name

    fun changeName(newName: String) {
        _name.value = newName
    }

    override fun onCleared() {
        super.onCleared()
        // ViewModel 被清除时调用
    }
}

在 Activity 中使用:

class MainActivity : AppCompatActivity() {

    private val viewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.name.collect { name ->
                    textView.text = name
                }
            }
        }
    }
}

4. ViewModel 常用方法和写法

1)viewModelScope

viewModelScope 是 ViewModel 中最常用的协程作用域。

class UserViewModel : ViewModel() {

    fun loadUser() {
        viewModelScope.launch {
            // 请求网络、查询数据库
        }
    }
}

当 ViewModel 被销毁时,viewModelScope 中的任务会自动取消。


2)onCleared()

ViewModel 被真正销毁时调用。

override fun onCleared() {
    super.onCleared()
    // 释放资源
}

例如关闭某些流、取消特殊任务等。

不过一般使用 viewModelScope 的话,不需要手动取消协程。


3)LiveData

以前常用,现在很多项目仍然在用。

class MainViewModel : ViewModel() {

    private val _name = MutableLiveData<String>()
    val name: LiveData<String> = _name

    fun changeName() {
        _name.value = "李四"
    }
}

Activity 观察:

viewModel.name.observe(this) { name ->
    textView.text = name
}

Fragment 里建议用:

viewModel.name.observe(viewLifecycleOwner) { name ->
    textView.text = name
}

4)StateFlow

现在更推荐的方式。

class MainViewModel : ViewModel() {

    private val _uiState = MutableStateFlow(MainUiState())
    val uiState: StateFlow<MainUiState> = _uiState

    fun updateTitle(title: String) {
        _uiState.value = _uiState.value.copy(title = title)
    }
}

data class MainUiState(
    val title: String = "",
    val loading: Boolean = false
)

Activity/Fragment 收集:

lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            textView.text = state.title
            progressBar.isVisible = state.loading
        }
    }
}

5. Lifecycle 和 ViewModel 的配合关系

一个常见结构是:

Activity / Fragment
    ↓ 观察数据
ViewModel
    ↓ 调用
Repository
    ↓ 获取数据
网络 / 数据库

职责划分:

Activity / Fragment

负责:

  • 初始化 View
  • 监听点击事件
  • 观察 ViewModel 数据
  • 根据数据更新 UI

不建议做:

  • 大量业务逻辑
  • 网络请求细节
  • 数据处理逻辑

ViewModel

负责:

  • 保存 UI 状态
  • 处理页面逻辑
  • 调用 Repository 获取数据
  • 暴露 LiveData / StateFlow 给界面

不建议做:

  • 持有 Activity/Fragment/View
  • 直接操作控件
  • 弹 Toast、跳页面这种强 UI 行为,除非用事件形式通知页面

Lifecycle

负责:

  • 感知当前页面状态
  • 控制协程、数据观察、资源释放
  • 避免内存泄漏和无效 UI 更新

6. 一个完整例子

ViewModel

class UserViewModel : ViewModel() {

    private val _uiState = MutableStateFlow(UserUiState())
    val uiState: StateFlow<UserUiState> = _uiState

    fun loadUser() {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(loading = true)

            try {
                delay(1000)
                _uiState.value = UserUiState(
                    loading = false,
                    name = "张三"
                )
            } catch (e: Exception) {
                _uiState.value = UserUiState(
                    loading = false,
                    error = "加载失败"
                )
            }
        }
    }
}

data class UserUiState(
    val loading: Boolean = false,
    val name: String = "",
    val error: String? = null
)

Activity

class UserActivity : AppCompatActivity() {

    private val viewModel: UserViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.uiState.collect { state ->
                    progressBar.isVisible = state.loading
                    nameTextView.text = state.name

                    state.error?.let {
                        Toast.makeText(this@UserActivity, it, Toast.LENGTH_SHORT).show()
                    }
                }
            }
        }

        viewModel.loadUser()
    }
}

这里:

  • Activity 负责显示 UI
  • ViewModel 负责加载和保存数据
  • Lifecycle 负责在合适生命周期收集数据

7. 最容易混淆的点

问题 1:ViewModel 会不会随着 Activity 的 onDestroy 一起销毁?

不一定。

比如屏幕旋转时:

旧 Activity onDestroy
新 Activity onCreate
ViewModel 不销毁

ViewModel 会被保留。

但如果用户真正退出页面,比如按返回键:

Activity finish
ViewModel onCleared

ViewModel 才销毁。


问题 2:为什么 ViewModel 不能持有 Activity?

因为 ViewModel 生命周期可能比 Activity 长。

如果 ViewModel 持有 Activity,屏幕旋转后旧 Activity 无法释放,容易造成内存泄漏。

错误示例:

class MainViewModel(val activity: Activity) : ViewModel()

不推荐。


问题 3:Fragment 中 observe 为什么用 viewLifecycleOwner?

Fragment 的生命周期和它的 View 生命周期不是完全一样的。

Fragment 可能还在,但它的 View 已经销毁了。

所以 Fragment 观察 LiveData 时推荐:

viewModel.data.observe(viewLifecycleOwner) {
    // 更新 UI
}

而不是:

viewModel.data.observe(this) {
    // 不推荐
}

8. 简单记忆法

你可以这样记:

Lifecycle:页面什么时候活着
ViewModel:页面活着时要显示什么数据

或者:

Lifecycle 管生命周期
ViewModel 管状态和数据
Activity/Fragment 管 UI 展示

常用组合:

private val viewModel: MainViewModel by viewModels()

lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        viewModel.uiState.collect { state ->
            // 更新 UI
        }
    }
}

这就是现在 Android 里非常常见、比较推荐的写法。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇