Q1:lifecycle 使用方式以及要解决的问题
LifeCycle 对外提供感知生命周期的能力,内部采用:“观察者模式”来实现。工作原理在框架层中实现,采用注入 HolderFragment 作为主题对象。其作用有两个方面:
- 感知生命周期状态以及Event --> State 状态转换.
- 分发 Event 给观察者。
初始化
public class LifeCycleDemoFragment extends Fragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_CREATE) {
Log.d("hlwang", "生命周期 onCreate....");
} else if (event == Lifecycle.Event.ON_RESUME) {
Log.d("hlwang", "生命周期 onResume....");
} else if (event == Lifecycle.Event.ON_START) {
Log.d("hlwang", "生命周期 onStart....");
} else if (event == Lifecycle.Event.ON_PAUSE) {
Log.d("hlwang", "生命周期 onPause....");
} else if (event == Lifecycle.Event.ON_STOP) {
Log.d("hlwang", "生命周期 onStop....");
} else if (event == Lifecycle.Event.ON_DESTROY) {
Log.d("hlwang", "生命周期 onDestory....");
}
}
});
}
}
作用
LifeCycle 提供了外部组件感知 Android Activity/Fragemnt生命周期的能力。松耦合的设计,提供了对象间一对多的依赖,当生命周期对象状态发生改变时,它的所有观察者都能收到通知并作出更新。
应用场景
- 判断应用是在前台还是在后台
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {// 页面在前台
} else {// 页面在后台
}
- 根据声明周期来做一些释放资源的操作。
- Handler 在 onDestory 中,移除不再使用的资源,避免内存泄漏MemoryLeak
- 可参考:AutoDisponse + RxLifeCycle
- Jetpack Lifecycle + LiveData 是级联的观察者
Q2:在不同的生命周期方法中,添加观察者,有什么需要额外注意的吗?
A2:在任何生命周期都可以通过getLifecycle().addObserver来添加观察者对象。但回调次数不一样。
如果在 onPause 中注册观察者,观察者的onStateChanged会执行多次!!!
即:
- 1、
onPause的生命周期 Event,会被解析成:STARTED的State。 - 2、当
getLifecycle().addObserver时,初始State =INITIALIZED。 - 3、从
INITIALIZED-->CREATED-->STARTED,onStateChanged会收到多次回调,从onCreate到onStop。
01-17 22:26:12.353 D/hlwang (12536): onPause ---> 生命周期 onCreate....
01-17 22:26:12.359 D/hlwang (12536): onPause ---> 生命周期 onStart....
01-17 22:26:12.930 D/hlwang (12536): onPause ---> 生命周期 onStop....
01-17 22:26:12.972 D/hlwang (12536): onPause ---> 生命周期 onDestory....
Q3:实现原理以及场景扩展
3.1、Activity
在 Activity 继承树中的ComponentActivity,ROM 源代码中应该是在 SupportActivity 中。在 onCreate 生命周期中,
path:androidx.activity.ComponentActivity
public class ComponentActivity extends androidx.core.app.ComponentActivity implements
LifecycleOwner,
ViewModelStoreOwner,
SavedStateRegistryOwner,
OnBackPressedDispatcherOwner {
/**
* {@inheritDoc}
*
* If your ComponentActivity is annotated with {@link ContentView}, this will
* call {@link #setContentView(int)} for you.
*/
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
}
3.2、Fragment
在 Fragment 实现类中,生命周期方法中,会看到类似这样的实现:
3.3、其他场景,例如:Application
如果,用户的客户端版本低,且迁移到androidx以及其他高版本成本较大,在这种情况下,也想使用 Lifecycle,那么,可以使用如下方式:
path:androidx.lifecycle.ProcessLifecycleOwner
public class ProcessLifecycleOwner implements LifecycleOwner {
ActivityInitializationListener mInitializationListener =
new ActivityInitializationListener() {
@Override
public void onCreate() {
}
@Override
public void onStart() {
activityStarted();
}
@Override
public void onResume() {
activityResumed();
}
};
void attach(Context context) {
mHandler = new Handler();
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
Application app = (Application) context.getApplicationContext();
app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
ReportFragment.get(activity).setProcessListener(mInitializationListener);
}
@Override
public void onActivityPaused(Activity activity) {
activityPaused();
}
@Override
public void onActivityStopped(Activity activity) {
activityStopped();
}
});
}
@NonNull
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
void activityStarted() {
mStartedCounter++;
if (mStartedCounter == 1 && mStopSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mStopSent = false;
}
}
void activityResumed() {
mResumedCounter++;
if (mResumedCounter == 1) {
if (mPauseSent) {
mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
mPauseSent = false;
} else {
mHandler.removeCallbacks(mDelayedPauseRunnable);
}
}
}
// ...
}