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
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout 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"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <View
- android:id="@+id/v_center_line"
- android:layout_width="match_parent"
- android:layout_height="1dp"
- app:layout_constraintBottom_toBottomOf="parent"
- app:layout_constraintTop_toTopOf="parent" />
-
- <androidx.appcompat.widget.AppCompatTextView
- android:id="@+id/tv_flag_left_vm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="LifeCycle操作演示"
- app:layout_constraintBottom_toTopOf="@id/v_center_line"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent" />
-
- <androidx.appcompat.widget.AppCompatButton
- android:id="@+id/btn_left_vm"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="查看ViewModel的值"
- android:textAllCaps="false"
- app:layout_constraintEnd_toEndOf="parent"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintTop_toBottomOf="@id/v_center_line" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
2. MockLocation.kt
- class MockLocation(private val owner: LifecycleOwner?, private val callBack: LocationCallBack?) :
- LifecycleEventObserver {
- private val TAG = MockLocation::class.java.simpleName
- private var enable = false
-
- // region 如此则会自动感知生命周期,并调用相应操作 ,如果是实现LifecycleObserver的接口,可以这么根据event单独处理。
- //如果是实现了LifecycleEventObserver,就不需要这个region块,而是使用onStateChanged的处理
- @OnLifecycleEvent(Lifecycle.Event.ON_START)
- fun onStart() {
- if (enable) {
- //开始定位,在此之前可能需要检测网络、用户信息、等各种状态,存在耗时,若不用lifecycle时候,就会出现在这里耗时检测
- // 而未真的start定位之前,activity就被stop,同时listener也被调用stop,即出现了本listener在start之前调用了stop的异常现象
-
- Log.i(TAG, "onStart")
- }
- }
-
- @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
- fun onStop() {
- // do some stop operate
- Log.i(TAG, "onStop")
- }
- //endregion
-
- /**
- * 开始模拟定位
- */
- fun startLocation() {
- enable = true
- if (owner!!.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
- //判断,如果没有开始定位,就再次开启定位,定位成功,使用callback回调UI刷新
- callBack?.onSuccess()
- }
- }
-
- override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
- when (event) {
- Lifecycle.Event.ON_CREATE -> {
- Log.i(TAG, "ON_CREATE")
- }
- Lifecycle.Event.ON_START -> {
- Log.i(TAG, "ON_START")
- }
- Lifecycle.Event.ON_RESUME -> {
- Log.i(TAG, "ON_RESUME")
- }
- Lifecycle.Event.ON_PAUSE -> {
- Log.i(TAG, "ON_PAUSE")
- }
- Lifecycle.Event.ON_STOP -> {
- Log.i(TAG, "ON_STOP")
- }
- Lifecycle.Event.ON_DESTROY -> {
- Log.i(TAG, "ON_DESTROY")
- }
- else -> {
- Log.i(TAG, "OTHER")
- }
- }
- }
-
- interface LocationCallBack {
- fun onSuccess()
- }
- }
3. 测试页面 LifeActivity.kt
- /**
- * LifeCycle的演示页面
- */
- class LifeActivity : AppCompatActivity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_lifecycle)
-
- btn_left_vm.setOnClickListener {
- startActivity(Intent(this, VmActivity::class.java))
- }
- //调用定位
- val mockLocation = MockLocation(this, object : MockLocation.LocationCallBack {
- override fun onSuccess() {
- //此时的回调,就是确保了,已经在UI显示的状态,
- Log.d("MockLocation", "onSuccess")
- }
- })
- mockLocation.startLocation()
- //mockLocation.onStart()
- //mockLocation.onStop()
-
- lifecycleScope.launchWhenCreated {
- Log.d("MockLocation", "launchWhenCreated")
- }
- }
-
- override fun onStart() {
- super.onStart()
-
- }
- }
4. LiftCycle 与 ViewModel
4.1 继承 ViewModel,Vvm.kt
- /**
- * ViewModel
- */
- class Vvm : ViewModel() {
- private val TAG = ViewModel::class.java.simpleName
-
- val vvm = "vvm 的 vvm"
-
- init {
- Log.d(TAG, "Vvm init")
- }
-
- override fun onCleared() {
- super.onCleared()
- Log.e(TAG, "Vvm onCleared")
- }
- }
-
- //android application 的viewModel
- class VaVm(application: Application) : AndroidViewModel(application) {
- private val TAG = ViewModel::class.java.simpleName
-
- val vam = "vApplication 的 vavm"
-
- init {
- Log.d(TAG, "VaVm init")
- }
-
- override fun onCleared() {
- super.onCleared()
- Log.e(TAG, "VaVm Cleared")
- }
- }
4.2 测试页面 VmActivity.kt
- class VmActivity : AppCompatActivity() {
- private val TAG = VmActivity::class.java.simpleName
-
- //创建方法
- val vm by viewModels
{ - defaultViewModelProviderFactory
- }
-
- val vavm by viewModels
{ - defaultViewModelProviderFactory
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_lifecycle)
-
- tv_flag_left_vm.text = "当前为 vm 的演示界面"
- btn_left_vm.text = "关闭"
- btn_left_vm.setOnClickListener { finish() }
- Log.i(TAG, "vm 的值 ${vm.vvm}")
- Log.i(TAG, "vavm 的值 ${vavm.vam}")
- //创建 vm 的方式,其实原理一样的
- val vvv = ViewModelProvider(this).get(Vvm::class.java)
- val vavm = ViewModelProvider(this).get(VaVm::class.java)
-
- Log.d(TAG, "vm的值 ${vvv.vvm}")
- Log.d(TAG,"vavm的值 ${vavm.vam}")
- }
- }