热搜:前端 nest neovim nvim

我尝试以最简单的方式帮你梳理 Lifecycle

lxf2023-05-08 01:03:30

前言

我们都知道 Activity 与 Fragment 都是有生命周期的,例如:onCreate()onStop() 这些回调方法就代表着其生命周期状态。我们开发者所做的一些操作都应该合理的控制在生命周期内,比如:当我们在某个 Activity 中注册了广播接收器,那么在其 onDestory() 前要记得注销掉,避免出现内存泄漏。

生命周期的存在,帮助我们更加方便地管理这些任务。但是,在日常开发中光凭 Activity 与 Fragment 可不够,我们通常还会使用一些组件来帮助我们实现需求,而这些组件就不像 Activity 与 Fragment 一样可以很方便地感知到生命周期了。

假设当前有这么一个需求:

开发一个简易的视频播放器组件以供项目使用,要求在进入页面后注册播放器并加载资源,一旦播放器所处的页面不可见或者不位于前台时就暂停播放,等到页面可见或者又恢复到前台时再继续播放,最后在页面销毁时则注销掉播放器。

试想一下:如果现在让你来实现该需求?你会怎么去实现呢?

实现这样的需求,我们的播放器组件就需要获取到所处页面的生命周期状态,在 onCreate() 中进行注册,onResume() 开始播放,onStop() 暂停播放,onDestroy() 注销播放器。

最简单的方法:提供方法,暴露给使用方,供其自己调用控制。

class VideoPlayerComponent(private val context: Context) {

    /**
     * 注册,加载资源
     */
    fun register() {
        loadResource(context)
    }

    /**
     * 注销,释放资源
     */
    fun unRegister() {
        releaseResource()
    }

    /**
     * 开始播放当前视频资源
     */
    fun startPlay() {
        startPlayVideo()
    }

    /**
     * 暂停播放
     */
    fun stopPlay() {
        stopPlayVideo()
    }
}

然后,我们的使用方MainActivity自己,主动在其相对应的生命周期状态进行控制调用相对应的方法。

class MainActivity : AppCompatActivity() {
    private lateinit var videoPlayerComponent: VideoPlayerComponent

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
	videoPlayerComponent = VideoPlayerComponent(this)
        videoPlayerComponent.register(this)
    }

    override fun onResume() {
        super.onResume()
        videoPlayerComponent.startPlay()
    }

    override fun onPause() {
        super.onPause()
        videoPlayerComponent.stopPlay()
    }

    override fun onDestroy() {
        videoPlayerComponent.unRegister()
        super.onDestroy()
    }

}

虽然实现了需求,但显然这不是最优雅的实现方式。一旦使用方忘记在 onDestroy() 进行注销播放器,就容易造成内存泄漏,而忘记注销显然是一件很容易发生的事情