在软件开发过程中,解耦是永恒的话题。而在Android应用开发过程中,解耦大多数是系统组件的生命周期与普通组件或者工具之间的解耦。我们再开发过程中依赖系统组件的生命周期,处理相关的一些操作,比如:activity、fragment、service、app进程的生命周期来处理一些普通组件的功能调用,有时候,我们不得不回调相关生命周期,完成对普通工具或组件的调用、控制、回收等操作。在普通组件无法感知生命周期的情况下,我们想要解耦,LifeCycle诞生了。
LifeCycle可以帮助我们这些开发者创建可感知的生命周期组件,这样的话,我们就可以在组件内管理自己的生命周期,从而降低模块间的耦合度。
案例说明
需求:
获取当前用户位置信息
未使用LifeCycle:
class OldDemoActivity: Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//初始化位置相关sdk或者工具
initLocation()
}
override fun onResume() {
super.onResume()
//获取定位信息
startGetLocation()
}
override fun onPause() {
super.onPause()
//停止获取定位
stopGetLocation()
}
private fun initLocation() {
TODO("Not yet implemented")
}
private fun startGetLocation() {
TODO("Not yet implemented")
}
private fun stopGetLocation() {
TODO("Not yet implemented")
}
override fun onDestroy() {
super.onDestroy()
}
}
从代码可以看出,获取定位信息这个需求实现,我们需要在不同的生命周期,处理不同的工作,完全依赖activity生命周期,而且代码与activity高度耦合。我们希望,获取定位信息这个功能,能封装成一个独立组件,与系统组件解耦,方便我们调用。
使用LifeCycle
优化之前的需求:
-
封装定位相关信息(类 MyLocationListener 、回调接口 OnLocationChangedListener )
class MyLocationListener//初始化位置相关sdk或者工具 (private var listener: OnLocationChangedListener) : LifecycleObserver { //相当于java代码中,构造函数中执行 init { initLocation() } private fun initLocation() { } /** * 获取定位信息 * 当Activity执行onResume()时,会自动调用此方法 */ @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun startGetLocation() { //获取定位后回调即可 listener.onLocationChanged(1.0, 1.0) } /** * 停止获取定位 * 当Activity执行onPause()时,会自动调用此方法 */ @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun stopGetLocation() { } } /** * 定位信息变化时回调 */ interface OnLocationChangedListener { fun onLocationChanged(latitude: Double, longitude: Double) }
-
修改activity代码即可完成
class NewDemoActivity : AppCompatActivity(), OnLocationChangedListener { private lateinit var locationListener: MyLocationListener override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) locationListener = MyLocationListener(this) //观察者绑定被观察者 lifecycle.addObserver(locationListener) } //位置信息的回调 override fun onLocationChanged(latitude: Double, longitude: Double) { } }
对比两次的实现,LifeCycle帮我们完美实现了组件对页面生命周期依赖问题,使组件自己管理自己的生命周期,这无疑大大降低了代码耦合度,提高了组件复用度,这在大型项目中无论是复用、扩展都非常好用。
LifeCycle原理
Jetpack为我们提供了两个类:LifecycleOwner(被观察者)和 LifecycleObserver(观察者)。通过观察者模式,实现对页面生命周期的监听。
通过查看源码:
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
ContextAware,
LifecycleOwner,
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner,
ActivityResultRegistryOwner,
ActivityResultCaller{}
我们发现ComponentActivity 已经实现了LifecycleOwner 接口。LifecycleOwner只有一个方法:
public interface LifecycleOwner {
/**
* Returns the Lifecycle of the provider.
*
* @return The lifecycle of the provider.
*/
@NonNull
Lifecycle getLifecycle();
}
LifecycleOwner通过该方法实现观察者模式的。内容如下:
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@NonNull
@Override
public Lifecycle getLifecycle() {
return mLifecycleRegistry;
}
按照这个思路,我们后续使用过程中,只需要实现观察者那部分代码即可,即实现 LifecycleObserver 接口。该接口没有接口方法,无需其它任何操作。我们上述的例子中,MyLocationListener 就是我们实现的观察者,之后被观察者给自己添加观察者就完成了LifeCycle的使用,使得普通组件获取了activity完整的生命周期。
总结
具有生命周期的组件:Activity,Fragment,Service以及Application,我们都可以使用相同或者类似的方式处理我们的功能业务。
- Fragment和Activity相同
- 使用LifecycleService解耦Service与组件
- 使用ProcessLifecycleOwner监听应用程序的生命周期:比如监听应用程序在前台还是后台等等