Jetpack之LifeCycle 一个可以感知宿主生命周期变化的组件

240 阅读3分钟

看看LifeCycle 官方文档吧

developer.android.google.cn/topic/libra…


一、LifeCycle是什么

LifeCycle 是一个可以感知宿主生命周期变化的组件。 常见的宿主包括 ActivityFragmentServiceApplication。当然了,用得最多的,就是Activity/Fragment

LifeCycle 会持有宿主的生命周期状态的信息,当宿主生命周期发生变化时,会通知监听宿主的观察者。

二、LifeCycle 能做什么

LifeCycle 的出现主要是为了解决:  系统组件的生命周期与普通组件之间的耦合性。

  • 系统组件指:Activity/Fragment、Service 和 Application。
  • 普通组件指:将代码按照功能或者作用封装成的组件。

举个例子,你有个视频播放器的类。

按照往常的做法,我们是在Activity或者Fragment的onPause之类的生命周期方法里面控制我们的视频播放器,这样,一来耦合严重,二来,这个控制周期,不是非常准确,不是很好控制。

而 LifeCycle ,就很好地解决了这个问题。

三、怎么使用

LifeCycle 的使用离不开两个类

被观察者:LifecycleOwner 和 观察者:LifecycleObserver

被观察者:LifecycleOwner:LifecycleOwner是一个接口,用于返回一个Lifecycle对象,表示生命周期拥有者,提供者,属于被观察的对象。

观察者:LifecycleObserver:LifecycleObserver是一个标记接口,任何类都可以通过实现该接口来感知组件生命周期的变化,属于观察对象。


二、四、典型应用

音频播放器的例子

  • 我们假设有一个播放器类,继承自LifecycleObserver,让其成为一个观察者。
  • 通过 addObserver 添加生命周期观察者。
  • MainActivity 调用下,观察周期变化。(LifecycleObserver 接口即可,该接口没有接口方法,不需要任何具体的实现。所以我们的 MainActivity 直接this就可以)

MyMediaPlayer是传统的写法

MyMediaPlayer2 是一种写法

MyMediaPlayer3是另外一种写法

implementation 'androidx.appcompat:appcompat:1.2.0'

Support Library 26.1.0及更高版本或AndroidX中FragmentActivity已实现了LifecycleOwner接口,所以自带引入的appcompat就可以实现 LifeCycle)

class MainActivity : AppCompatActivity() {

//    private val mockPlayer = MyMediaPlayer()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
//        mockPlayer.onCreate()
        MyMediaPlayer2(this)
//        MyMediaPlayer3(this)
        Log.i("MainActivity", "onCreate")
    }
}

  • MyMediaPlayer (用于演示的,无生命周期感知的 media player)

/**
 *
 * 用于演示的,无生命周期感知的 media player
 */
class MyMediaPlayer {

    private lateinit var player: MediaPlayer


    fun onCreate() {
        player = MediaPlayer()
        Log.d("MyMediaPlayer", "onCreate")
    }

    fun onResume() {
        thread {
            SystemClock.sleep(3000)//模拟阻塞1s
            player.start()
            Log.d("MyMediaPlayer", "onResume")
        }
    }

    fun onPause() {
        player.stop()
        Log.d("MyMediaPlayer", "onPause")
    }

    fun onDestroy() {
        player.release()
        Log.d("MyMediaPlayer", "onDestroy")
    }

}

MyMediaPlayer2


class MyMediaPlayer2(private val owner: LifecycleOwner) : LifecycleObserver {

    private lateinit var player: MediaPlayer

    init {
        //关联生命周期的观察者
        owner.lifecycle.addObserver(this)
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreate() {
        player = MediaPlayer()
        Log.d("MyMediaPlayer2", "onCreate")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
        thread {

            SystemClock.sleep(3000)//模拟阻塞1s
            if (owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
                player.start()
                Log.d("MyMediaPlayer2", "onResume")
            }
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onPause() {
        player.stop()
        Log.d("MyMediaPlayer2", "onPause")
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        player.release()
        Log.d("MyMediaPlayer2", "onDestroy")
    }

}


  • MyMediaPlayer3


class MyMediaPlayer3(private val owner: LifecycleOwner) : LifecycleEventObserver {

    private lateinit var player: MediaPlayer

    init {
        //关联生命周期的观察者
        owner.lifecycle.addObserver(this)
    }

    override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
        when (event) {
            Lifecycle.Event.ON_CREATE -> {
                Log.d("MyMediaPlayer3", "onCreate")
                player = MediaPlayer()
            }
            Lifecycle.Event.ON_START, Lifecycle.Event.ON_RESUME -> {
                if (owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
                    player.start()
                    Log.d("MyMediaPlayer3", "onResume")
                }
            }
            Lifecycle.Event.ON_PAUSE, Lifecycle.Event.ON_STOP -> {
                player.stop()
                Log.d("MyMediaPlayer3", "onPause")
            }
            Lifecycle.Event.ON_DESTROY -> {
                player.release()
                Log.d("MyMediaPlayer3", "onDestroy")
            }
            Lifecycle.Event.ON_ANY -> Log.d("MyMediaPlayer3", "onAny")
        }
    }

}

.
.
运行起来之后,我们看到对应的日志产生。

运行,MyMediaPlayer2

MyMediaPlayer2: onCreate
MyMediaPlayer2: onResume

运行,MyMediaPlayer3

MyMediaPlayer3: onCreate
MyMediaPlayer3: onResume
MyMediaPlayer3: onResume

以上的例子和 LifeCycle 和 Activity结合。

如果是跟Service或者Application结合,不是这么写,但是大同小异,具体可以参考这篇文章。

zhuanlan.zhihu.com/p/255168699

来个例子 LifeCycle结合Dialog

当Dialog所依附的Activity被销毁时,Dialog也可以自动关闭,再也不用担心Dialog的内存泄漏问题了

class TipDialog(context: Context) : Dialog(context), LifecycleObserver {
    init {
        if (context is ComponentActivity) {
            (context as ComponentActivity).lifecycle.addObserver(this)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.item_tip_dialog)
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    private fun onDestroy() {
        // 当Dialog所依附的Activity被销毁时,Dialog也可以自动关闭,再也不用担心Dialog的内存泄漏问题了
        if (isShowing) {
            dismiss()
        }
    }
}

比较新的版本中 ,OnLifecycleEvent已经废弃。官方建议使用 LifecycleEventObserver 或者 DefaultLifecycleObserver 替代 本文。

先写到这里吧。