引言
Lifecycle组件是Android Jetpack架构组件之一,它提供了一种方法来管理Android组件(如Activity、Fragment和服务)的生命周期。Lifecycle组件帮助你执行与生命周期相关联的操作,确保在适当的时间发生适当的事情,例如,当你的应用进入后台时停止数据刷新,或者在应用回到前台时更新UI。
使用Lifecycle解耦页面与组件
Lifecycle
组件提供了一种方法来处理 Android 组件(如 Activity 和 Fragment)的生命周期。在 MVVM 架构中,Lifecycle 组件可以帮助 ViewModel 感知宿主的生命周期状态,从而在适当的时机进行数据加载或资源清理。
介绍一个控件:Chronometer是 Android 提供的一个用于显示计时器的 UI 控件。它继承自
View
类,专门用于展示和跟踪时间的流逝。Chronometer
控件不仅可以显示经过的时间,还可以在时间变化时提供格式化的文本显示,并且可以响应用户的开始、暂停和重置等操作
我们就使用这个控件来体验Lifecycle的作用,在活动当中放置一个Chronometer控件用来计算我们使用这个程序多长时间,按照之前所学的我们会在活动的回调函数当中写代码
public class MainActivity extends AppCompatActivity {
Chronometer chronometer;
long l;
@Override
protected void onCreate(Bundle savedInstanceState) {
......
chronometer = findViewById(R.id.chronometer);
}
@Override
protected void onResume() {
super.onResume();
//SystemClock.elapsedRealtime() 返回自开机以来经过的时间(以毫秒为单位),l 是之前保存的时间差值。
//通过减去 l,计时器的基准时间被设置为上次暂停时的时间。
chronometer.setBase(SystemClock.elapsedRealtime() - l);
chronometer.start();
}
@Override
protected void onPause() {
super.onPause();
//后台运行计算并保存当前的时间差值。chronometer.getBase() 返回计时器的基准时间,通过计算当前时间减去基准时间,
//可以得到从基准时间到当前时间经过的毫秒数,这个值被保存在 l 中,以便在下次 onResume() 时使用。
l = SystemClock.elapsedRealtime() - chronometer.getBase();
chronometer.stop();
}
}
chronometer.setBase(SystemClock.elapsedRealtime() - l);
设置计时器的基底时间。这里l
是之前保存的时间差,这样做是为了在 Activity 从onPause
回来时,计时器能够从上次暂停的地方继续计时l = SystemClock.elapsedRealtime() - chronometer.getBase();
计算当前时间与计时器基底时间的差值,并将其保存在l
中。这个值将在下次onResume
时使用,以确保计时器的连续性
如何进行解耦呢?接下来就看看吧
public class MyChronomter extends Chronometer implements LifecycleObserver {
private long l;
public MyChronomter(Context context, AttributeSet attrs) {
super(context, attrs);
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void startMeter() {
setBase(SystemClock.elapsedRealtime() - l);
start();
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private void stopMeter() {
l = SystemClock.elapsedRealtime() - getBase();
stop();
}
}
我们新创建了一个组件实现LifecycleObserver
LifecycleObserver
是 Android Architecture Components 中Lifecycle
组件的一部分。它是一个接口,用于定义一个观察者,它可以观察到LifecycleOwner
生命周期的变化
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
标记,这意味着当关联的 LifecycleOwner
从暂停状态恢复到前台(即 ON_RESUME
事件)时,这个方法会被调用,使用注解来明确调用的时间
代码不难理解,接下来我们就可以把主活动里面的多于代码删除了,但要为组件设置监听
getLifecycle().addObserver(chronometer); //给他设置监听
接下来运行程序就仍然实现了之前的记录下应用的使用时间,大大减少了活动里面代码的数量。
使用LifecycleService解耦Service组件
LifecycleService
是一个非常有用的组件,它允许你将后台服务(Service
)与组件的生命周期解耦。这样,服务可以在不需要与特定活动(Activity
)或片段(Fragment
)紧密绑定的情况下运行
我们需要先导入依赖:
也可以直接使用快捷键F4
对你所要导入的依赖进行搜索与选择
点击OK就导入成功了!
接下开看看如何使用吧
- 创建
LifecycleService
子类:首先,你需要创建一个继承自LifecycleService
的类。这将是你的服务类,你可以在这里定义服务的行为。
public class MyLocationService extends LifecycleService {
public MyLocationService() {
Log.d("hhhhhh","MyLocationService");
MyLocationObserver observer = new MyLocationObserver(this);
getLifecycle().addObserver(observer);
}
}
我们定义了一个服务,并为其设置监听
- 注册
LifecycleObserver
:在你的LifecycleService
子类中,你需要注册一个或多个LifecycleObserver
。这些观察者将监听生命周期事件,并在事件发生时执行相应的操作。 - 处理生命周期事件:在
LifecycleObserver
中,你可以使用@OnLifecycleEvent
注解来标记方法,这些方法将在特定的生命周期事件发生时被调用。
public class MyLocationObserver implements LifecycleObserver {
private Context context;
private LocationManager locationManager;
private MyLocationListener listener;
public MyLocationObserver(Context context) {
this.context = context;
}
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void startGetLocation() {
Log.d("hhhhhh","startGetLocation");
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates
(LocationManager.GPS_PROVIDER, 300,
1, listener);
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void stopGetLocation() {
Log.d("hhhhhh","stopGetLocation");
locationManager.removeUpdates(listener);
}
static class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(@NonNull Location location) {
Log.d("hhhhhh","LocationChanged" + location.toString());
}
}
}
上面的注解就无需再做过多的解释了,在上面解耦页面的时候就已经介绍过了,对部分不熟悉的代码进行简单介绍吧:
locationManager.requestLocationUpdates
:这个方法请求位置更新,指定使用GPS_PROVIDER
,设置更新的时间间隔为 300 毫秒,水平精度为 1 米,并将listener
作为回调。locationManager.removeUpdates(listener)
:当不再需要位置更新时,这个方法将停止位置更新,以避免不必要的资源消耗和电池使用。
- 在清单文件中注册服务:最后,你需要在Android项目的清单文件(
AndroidManifest.xml
)中注册你的LifecycleService
。
<service
android:name=".MyLocationService"
android:enabled="true"
android:exported="true"></service>
接下来运行程序,当我们按下开始按钮再按下结束按钮,此时观察打印日志:
使用ProcessLifecycleOwner监听应用程序生命周期
我们先来看看如何使用吧
- 创建
LifecycleObserver
public class MyApplicationObserve implements LifecycleObserver {
private static String TAG = "hhhhhh";
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
private void onCreate() {
Log.d(TAG, "onCreate");
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
private void onStart() {
Log.d(TAG, "onStart");
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void onResume() {
Log.d(TAG, "onResume");
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private void onPause() {
Log.d(TAG, "onPause");
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
private void onStop() {
Log.d(TAG, "onStop");
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void onDestroy() {
Log.d(TAG, "onDestroy");
}
}
- 注册
LifecycleObserver
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ProcessLifecycleOwner.get().getLifecycle()
.addObserver(new MyApplicationObserve());
}
}
ProcessLifecycleOwner.get().getLifecycle()
通过ProcessLifecycleOwner
的单例实例获取整个应用程序进程的Lifecycle
对象。addObserver(new MyApplicationObserve())
为Lifecycle
对象添加一个新的观察者MyApplicationObserve
。当应用程序的生命周期发生变化时,这个观察者将收到通
<application android:name=".MyApplication">
这行代码位于 AndroidManifest.xml 文件中,它指定了 MyApplication
作为应用程序的入口类
使用
ProcessLifecycleOwner
时需要注意以下几点:
ON_CREATE
事件只会被分发一次,即应用程序启动时。ON_DESTROY
事件永远不会被分发,因为进程的生命周期直到进程被系统终止才会结束。ON_START
,ON_RESUME
,ON_PAUSE
,ON_STOP
事件会随着活动的生命周期变化而分发,但可能会有延迟,因为系统要确保不会因为活动的配置更改(如屏幕旋转)而重复发送这些事件。
接下来运行程序,我们推到后台一次,再进去最后停止运行程序:
文章到这里就结束了!