【1】LifeCycle
Lifecycle,顾名思义,是用于帮助开发者管理Activity和Fragment 的生命周期,它是LiveData和ViewModel的基础。下面就先介绍为何及如何使用Lifecycle。
①使用LifeCycle有什么好处?
LifeCycle可以帮助开发者创建可感知生命周期的组件。这样,组件便能够在其内部管理自己的生命周期,从而降低模块间的耦合度,并降低内存泄漏发生的可能性
- 举个例子,我们经常需要在页面的onCreate()方法中对组件进行初始化,在onPause()方法中停止组件,而在页面的onDestroy()方法中对组件进行资源回收工作。这样的工作非常烦琐,会让页面与组件之间的耦合度变高。但这些工作又不得不做,因为这可能会引发内存泄漏。
②不使用LifeCycle管理我们通常是这样的:
class MyLocationListener {
public MyLocationListener(Context context, Callback callback) {
// ...
}
void start() {
// 连接系统定位服务
}
void stop() {
// 断开系统定位服务
}
}
class MyActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
public void onCreate(...) {
myLocationListener = new MyLocationListener(this, (location) -> {
// 更新 UI
});
}
@Override
public void onStart() {
super.onStart();
myLocationListener.start();
// 管理其他需要响应activity生命周期的组件
}
@Override
public void onStop() {
super.onStop();
myLocationListener.stop();
// 管理其他需要响应activity生命周期的组件
}
}
问题分析:
虽然此示例看起来没问题,但在真实的应用中,最终会有太多管理界面和其他组件的调用,以响应生命周期的当前状态。管理多个组件会在生命周期方法(如onStart() 和 onStop())中放置大量的代码,这使得它们难以维护。 此外,无法保证组件会在 Activity 或Fragment 停止之前启动myLocationListener。在我们需要执行长时间运行的操作(如 onStart()中的某种配置检查)时尤其如此。在这种情况下,myLocationListener的onStop() 方法会在 onStart()之前调用,这使得组件留存的时间比所需的时间要长,从而导致内次泄漏。
- activity的生命周期内有大量管理组件的代码,难以维护。
- 无法保证组件会在 Activity/Fragment停止后不执行启动。
【2】如何正确的使用LifeCycle?
- 使用思路:
- 构建一个 Lifecycle 对象(通过一个实现了 LifecycleOwner 接口的对象的 getLifecycle()方法返回),这个对象就是一个被观察者,具有生命周期感知能力
- 构建一个 LifecycleObserver 对象,它对指定的 Lifecycle 对象进行监听
- 通过将 Lifecycle 对象的 addObserver(…) 方法,将 Lifecycle 对象和 LifecycleObserver 对象进行绑定
①导入依赖(这里直接去官网看最新的版本导入就可以了)
这里给出一些,按需选择,并不是全部都需要的
dependencies {
def lifecycle_version = "2.2.0"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// 只有Lifecycles (不带 ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// lifecycle注解处理器
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// 替换 - 如果使用Java8,就用这个替换上面的lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
//以下按需引入
// 可选 - 帮助实现Service的LifecycleOwner
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// 可选 - ProcessLifecycleOwner给整个 app进程 提供一个lifecycle
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// 可选 - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// 可选 - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
}
②创建一个类实现LifecycleOwner:
public class MyLocationListener implements LifecycleObserver {
public MyLocationListener(Activity context, OnLocationChangeListener listener) {
//初始化操作
iniLocationManager();
}
private void iniLocationManager() {
}
//当Activity执行onResume()方法时,该方法会被自动调用
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private void startGetLocation(){
Log.e("true","onResume"+"被调用了");
}
//当Activity执行onPause()方法时,该方法会被自动调用
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private void stopGetLocation(){
Log.e("true","onPause"+"被调用了");
}
//当Activity执行onDestroy()方法时,该方法会被自动调用
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
private void delGetLocation(){
Log.e("true","onDestroy"+"被调用了");
}
//当地理位置发送改变时,通过该接口通知调用者
public interface OnLocationChangeListener{
void onChanged(double latitude,double longitude);
}
}
按照需求通过注解的方式来实现方法的调用。
③在需要被观察的activity或者fragment中添加Lifecycle对象,并且添加observer。
- 主MainActivity
在MainActivity中,只需要引用MyLocationListener即可,不用再关心Activity生命周期变化对该组件所带来的影响。生命周期的管理完全交给MyLocationListener内部自行处理。在Activity中要做的只是通过getLifecycle().addObserver()方法,将观察者与被观察者绑定起来,代码如下:
public class MainActivity extends AppCompatActivity {
private MyLocationListener myLocationListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myLocationListener = new MyLocationListener(this, new MyLocationListener.OnLocationChangeListener() {
@Override
public void onChanged(double latitude, double longitude) {
//展示收到的位置信息
}
});
//将观察者与被观察者绑定
getLifecycle().addObserver(myLocationListener);
}
}