
在 Android 开发中,一个常见的痛点是如何让自定义组件或对象感知系统组件(如 Activity、Fragment)的生命周期,以便在适当的时机执行初始化和资源清理,避免内存泄漏。传统的做法是将业务逻辑直接写在 Activity 的生命周期回调中,导致两者高度耦合,代码难以维护和复用。
Jetpack Lifecycle 组件的诞生,正是为了解决这一问题。它提供了一套可感知生命周期的架构组件,允许我们构建能够自主管理其生命周期的类,从而将业务逻辑从系统组件中解耦出来。
为什么需要 Lifecycle:解耦系统组件与普通组件
在没有 Lifecycle 之前,一个普通组件(例如一个计时器)的生命周期逻辑必须强依赖于其宿主 Activity 的生命周期。如下图所示,这种紧密耦合使得组件难以独立测试和复用。

系统组件
onCreate
...
onDestroy
通知
普通组件
代码实例一:使用 Lifecycle 解耦 Activity 与 Chronometer
我们以一个 Chronometer(计时器)组件为例。其业务需求是:当界面显示(onResume)时开始计时,当界面隐藏(onPause)时暂停计时。
在传统的紧耦合实现中,所有逻辑都写在 MainActivity 中:
MainActivity.java (传统紧耦合实现)
package com.example.lifecycle;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.Chronometer;
public class MainActivity extends AppCompatActivity {
private Chronometer chronometer;
private Long elapseTime = 0l;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer = findViewById(R.id.chronometer);
}
@Override
protected void onResume() {
super.onResume();
// 恢复计时
chronometer.setBase(SystemClock.elapsedRealtime() - elapseTime);
chronometer.start();
}
@Override
protected void onPause() {
super.onPause();
// 记录已计时长并暂停
elapseTime = SystemClock.elapsedRealtime() - chronometer.getBase();
chronometer.stop();
}
}
这种模式下,Chronometer 的生命周期逻辑与 Activity 深度绑定,完全不具备独立性和可复用性。
现在,我们使用 Lifecycle 进行改造。核心思想是让自定义组件实现 LifecycleObserver 接口,从而能够观察宿主(这里是 Activity)的生命周期变化。
首先,宿主 Activity 只需将自定义组件注册为观察者:
MainActivity2.java (解耦后)
package com.example.lifecycle;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity2 extends AppCompatActivity {
private MyChronometer chronometer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chronometer = findViewById(R.id.chronometer);
// 关键步骤:将自定义组件添加为生命周期观察者
getLifecycle().addObserver(chronometer);
}
}
然后,我们创建自定义的 MyChronometer 类,让它继承 Chronometer 并实现 LifecycleObserver。通过 @OnLifecycleEvent 注解,可以声明在特定生命周期事件发生时需要执行的方法。
MyChronometer.java (生命周期感知组件)
package com.example.lifecycle;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.widget.Chronometer;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
public class MyChronometer extends Chronometer implements LifecycleObserver {
private Long elapseTime = 0l;
public MyChronometer(Context context, AttributeSet attrs) {
super(context, attrs);
}
// 当观察到宿主进入 ON_RESUME 状态时,开始计时
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
public void startMeter() {
setBase(SystemClock.elapsedRealtime() - elapseTime);
start();
}
// 当观察到宿主进入 ON_PAUSE 状态时,暂停计时
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
public void stopMeter() {
elapseTime = SystemClock.elapsedRealtime() - getBase();
stop();
}
}
布局文件 activity_main.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"
tools:context=".MainActivity">
<com.example.lifecycle.MyChronometer
android:id="@+id/chronometer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:textSize="36sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
经过此番改造,MyChronometer 内部封装了自身的生命周期逻辑,Activity 仅作为生命周期的提供者(LifecycleOwner),无需关心具体细节。这大大降低了模块间的耦合度,使组件可以在任何拥有生命周期的上下文中复用,极大提升了代码的清晰度和可维护性,这也是现代 Android/iOS 架构追求的目标。
代码实例二:使用 LifecycleService 解耦 Service 与组件
Lifecycle 的能力不仅限于 Activity 和 Fragment,通过 LifecycleService 同样可以应用在 Service 中。下面的例子展示了一个后台定位服务如何利用 Lifecycle 管理定位监听器的生命周期。
1. 添加依赖
在 app/build.gradle 中添加扩展库依赖(注意版本可能有更新):
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha02'
2. 创建自定义 Service
继承 LifecycleService,并在构造方法中注册生命周期观察者。
MyLocationService.java
package com.example.lifecycle;
import android.util.Log;
import androidx.lifecycle.LifecycleService;
public class MyLocationService extends LifecycleService {
public MyLocationService() {
Log.d("liang", "MyLocationService");
MyLocationObserver myLocationObserver = new MyLocationObserver(this);
getLifecycle().addObserver(myLocationObserver);
}
}
3. 创建生命周期观察者
观察者 MyLocationObserver 在 Service 的 ON_CREATE 事件中开始定位,在 ON_DESTROY 事件中停止定位。
MyLocationObserver.java
package com.example.lifecycle;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import androidx.core.app.ActivityCompat;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.OnLifecycleEvent;
public class MyLocationObserver implements LifecycleObserver {
private Context context;
private LocationManager locationManager;
private MyLocationListener myLocationListener;
public MyLocationObserver(Context context) {
this.context = context;
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
public void startGetLocation() {
Log.d("liang", "startGetLocation");
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
myLocationListener = new MyLocationListener();
// 检查权限(实际开发中应使用更完善的权限请求流程)
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 1, myLocationListener);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void stopGetLocation() {
Log.d("liang", "stopGetLocation");
locationManager.removeUpdates(myLocationListener);
}
static class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
Log.d("liang", "location changed" + location.toString());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
}
}
4. 配置与启动
需要在 AndroidManifest.xml 中声明权限和服务,并通过一个简单的 Activity 来控制服务的启停。这种基于生命周期的管理方式,如同 Java Spring 框架中的容器管理Bean生命周期一样,能够确保资源被正确初始化和释放,有效避免了因忘记注销监听器而导致的内存泄漏或后台耗电问题。
模拟位置变化(测试用)
在终端使用 ADB 命令可以模拟 GPS 位置更新,便于测试:
adb -s emulator-5554 emu geo fix 121.4961236714487 31.244010934431345
LifeCycle 带来的核心优势
总结来说,使用 Lifecycle 组件能带来以下显著好处:
- 构建生命周期感知组件:让任意类能够自主响应生命周期状态变化,实现更清晰的职责分离。
- 降低模块耦合度:组件内部管理自身逻辑,与
Activity、Fragment 等系统组件解耦,提升代码的可测试性和复用性。
- 减少内存泄漏风险:通过在合适的生命周期节点(如
ON_DESTROY)自动释放资源,减少了因疏忽造成的内存泄漏。
- 统一的支持范围:
Activity、Fragment、Service 乃至 Application 都支持作为 LifecycleOwner,为不同场景下的解耦提供了统一方案。
通过上述实例可以看出,Lifecycle 是构建健壮、可维护 Android 应用的基础,是掌握 Jetpack 架构组件的重要第一步。