• LifeCycle 的使用和原理


    LifeCycle说明:
        1、使用mockLocation,此LifeActivity是ComponentActivity的子类,所以也是LifeCycleOwner的实现类
        2、MockLocation模拟定位服务,这里面就持有了lifeCycleOwner,且其实现了LifeCycleObserver,就能感知到UI的生命周期
        3、如此调用,则定位服务就能根据生命周期,来决定回调。
        4、倘若没有这类生命周期管理,需要手动关联,onStart定位 onStop 停止,则会出现在onCreate中调用startLocation的话,
        由于某些异常情况,导致可能会出现,先走到了location的onStop,后 onStart,可能就出异常报错。

    1. 布局xml文件 activity_lifecycle.xml

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:app="http://schemas.android.com/apk/res-auto"
    4. xmlns:tools="http://schemas.android.com/tools"
    5. android:layout_width="match_parent"
    6. android:layout_height="match_parent">
    7. <View
    8. android:id="@+id/v_center_line"
    9. android:layout_width="match_parent"
    10. android:layout_height="1dp"
    11. app:layout_constraintBottom_toBottomOf="parent"
    12. app:layout_constraintTop_toTopOf="parent" />
    13. <androidx.appcompat.widget.AppCompatTextView
    14. android:id="@+id/tv_flag_left_vm"
    15. android:layout_width="wrap_content"
    16. android:layout_height="wrap_content"
    17. android:text="LifeCycle操作演示"
    18. app:layout_constraintBottom_toTopOf="@id/v_center_line"
    19. app:layout_constraintEnd_toEndOf="parent"
    20. app:layout_constraintStart_toStartOf="parent" />
    21. <androidx.appcompat.widget.AppCompatButton
    22. android:id="@+id/btn_left_vm"
    23. android:layout_width="wrap_content"
    24. android:layout_height="wrap_content"
    25. android:text="查看ViewModel的值"
    26. android:textAllCaps="false"
    27. app:layout_constraintEnd_toEndOf="parent"
    28. app:layout_constraintStart_toStartOf="parent"
    29. app:layout_constraintTop_toBottomOf="@id/v_center_line" />
    30. </androidx.constraintlayout.widget.ConstraintLayout>

    2. MockLocation.kt

    1. class MockLocation(private val owner: LifecycleOwner?, private val callBack: LocationCallBack?) :
    2. LifecycleEventObserver {
    3. private val TAG = MockLocation::class.java.simpleName
    4. private var enable = false
    5. // region 如此则会自动感知生命周期,并调用相应操作 ,如果是实现LifecycleObserver的接口,可以这么根据event单独处理。
    6. //如果是实现了LifecycleEventObserver,就不需要这个region块,而是使用onStateChanged的处理
    7. @OnLifecycleEvent(Lifecycle.Event.ON_START)
    8. fun onStart() {
    9. if (enable) {
    10. //开始定位,在此之前可能需要检测网络、用户信息、等各种状态,存在耗时,若不用lifecycle时候,就会出现在这里耗时检测
    11. // 而未真的start定位之前,activity就被stop,同时listener也被调用stop,即出现了本listener在start之前调用了stop的异常现象
    12. Log.i(TAG, "onStart")
    13. }
    14. }
    15. @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    16. fun onStop() {
    17. // do some stop operate
    18. Log.i(TAG, "onStop")
    19. }
    20. //endregion
    21. /**
    22. * 开始模拟定位
    23. */
    24. fun startLocation() {
    25. enable = true
    26. if (owner!!.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
    27. //判断,如果没有开始定位,就再次开启定位,定位成功,使用callback回调UI刷新
    28. callBack?.onSuccess()
    29. }
    30. }
    31. override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
    32. when (event) {
    33. Lifecycle.Event.ON_CREATE -> {
    34. Log.i(TAG, "ON_CREATE")
    35. }
    36. Lifecycle.Event.ON_START -> {
    37. Log.i(TAG, "ON_START")
    38. }
    39. Lifecycle.Event.ON_RESUME -> {
    40. Log.i(TAG, "ON_RESUME")
    41. }
    42. Lifecycle.Event.ON_PAUSE -> {
    43. Log.i(TAG, "ON_PAUSE")
    44. }
    45. Lifecycle.Event.ON_STOP -> {
    46. Log.i(TAG, "ON_STOP")
    47. }
    48. Lifecycle.Event.ON_DESTROY -> {
    49. Log.i(TAG, "ON_DESTROY")
    50. }
    51. else -> {
    52. Log.i(TAG, "OTHER")
    53. }
    54. }
    55. }
    56. interface LocationCallBack {
    57. fun onSuccess()
    58. }
    59. }

    3. 测试页面 LifeActivity.kt

    1. /**
    2. * LifeCycle的演示页面
    3. */
    4. class LifeActivity : AppCompatActivity() {
    5. override fun onCreate(savedInstanceState: Bundle?) {
    6. super.onCreate(savedInstanceState)
    7. setContentView(R.layout.activity_lifecycle)
    8. btn_left_vm.setOnClickListener {
    9. startActivity(Intent(this, VmActivity::class.java))
    10. }
    11. //调用定位
    12. val mockLocation = MockLocation(this, object : MockLocation.LocationCallBack {
    13. override fun onSuccess() {
    14. //此时的回调,就是确保了,已经在UI显示的状态,
    15. Log.d("MockLocation", "onSuccess")
    16. }
    17. })
    18. mockLocation.startLocation()
    19. //mockLocation.onStart()
    20. //mockLocation.onStop()
    21. lifecycleScope.launchWhenCreated {
    22. Log.d("MockLocation", "launchWhenCreated")
    23. }
    24. }
    25. override fun onStart() {
    26. super.onStart()
    27. }
    28. }

    4. LiftCycle 与 ViewModel
      4.1 继承 ViewModel,Vvm.kt

    1. /**
    2. * ViewModel
    3. */
    4. class Vvm : ViewModel() {
    5. private val TAG = ViewModel::class.java.simpleName
    6. val vvm = "vvm 的 vvm"
    7. init {
    8. Log.d(TAG, "Vvm init")
    9. }
    10. override fun onCleared() {
    11. super.onCleared()
    12. Log.e(TAG, "Vvm onCleared")
    13. }
    14. }
    15. //android application 的viewModel
    16. class VaVm(application: Application) : AndroidViewModel(application) {
    17. private val TAG = ViewModel::class.java.simpleName
    18. val vam = "vApplication 的 vavm"
    19. init {
    20. Log.d(TAG, "VaVm init")
    21. }
    22. override fun onCleared() {
    23. super.onCleared()
    24. Log.e(TAG, "VaVm Cleared")
    25. }
    26. }

      4.2 测试页面 VmActivity.kt

    1. class VmActivity : AppCompatActivity() {
    2. private val TAG = VmActivity::class.java.simpleName
    3. //创建方法
    4. val vm by viewModels {
    5. defaultViewModelProviderFactory
    6. }
    7. val vavm by viewModels {
    8. defaultViewModelProviderFactory
    9. }
    10. override fun onCreate(savedInstanceState: Bundle?) {
    11. super.onCreate(savedInstanceState)
    12. setContentView(R.layout.activity_lifecycle)
    13. tv_flag_left_vm.text = "当前为 vm 的演示界面"
    14. btn_left_vm.text = "关闭"
    15. btn_left_vm.setOnClickListener { finish() }
    16. Log.i(TAG, "vm 的值 ${vm.vvm}")
    17. Log.i(TAG, "vavm 的值 ${vavm.vam}")
    18. //创建 vm 的方式,其实原理一样的
    19. val vvv = ViewModelProvider(this).get(Vvm::class.java)
    20. val vavm = ViewModelProvider(this).get(VaVm::class.java)
    21. Log.d(TAG, "vm的值 ${vvv.vvm}")
    22. Log.d(TAG,"vavm的值 ${vavm.vam}")
    23. }
    24. }

  • 相关阅读:
    3-JS利用模板
    每日一题 136. 只出现一次的数字(简单,位运算)
    Hadoop快速上手-1
    阿里邮箱/网易邮箱个人版设置POP3使用
    认识网线上的各种参数标号
    Go语言教程
    【C++】List -- 详解
    嵌入式开发实战系列:QSPI Flash驱动功能解析
    太阳直散追踪器
    Java类初始化、实例化流程你真的清楚吗
  • 原文地址:https://blog.csdn.net/u011193452/article/details/126408664