Activity/Fragment的生命周期每一个Android的开发人员几乎每一天都要打交道,其重要性不言而喻。那么你知道几种监听回调的方法呢:直接重写Activity/Fragment生命周期方法?通过Application#registerActivityLifecycleCallbacks()/FragmentManager#registerFragmentLifecycleCallbacks()注册回调?实现LifecycleObserver接口?继承BaseActivity/BaseFragment?方法多多,让我们逐条一起展开看看吧!
#1.直接重写Activity/Fragment生命周期方法
这里展开就有些老生常谈了。但还是有一点值得一提,那就是Android几乎每一个生命周期回调都会要求调用父类方法,如果不调用将会报错,而检测是否调用的核心就是Activity.mCalled变量,通过对该变量的判断,便可知道是否调用了父类方法。当然针对编译器的检测,则是通过@CallSuper注解实现的。
###优点:能够覆盖到所有暴露的生命周期方法。
###缺点:仅能针对自己工程的Activity进行覆写,拥有一定的局限性。
#2.registerLifecycleCallbacks
##a.添加Activity回调
Application#registerActivityLifecycleCallbacks()这一API是在API Level 14后添加的。通过该方法,我们可以传递一个ActivityLifecycleCallbacks的实例,该接口声明如下:
public interface ActivityLifecycleCallbacks {
void onActivityCreated(Activity activity, Bundle savedInstanceState);
void onActivityStarted(Activity activity);
void onActivityResumed(Activity activity);
void onActivityPaused(Activity activity);
void onActivityStopped(Activity activity);
void onActivitySaveInstanceState(Activity activity, Bundle outState);
void onActivityDestroyed(Activity activity);
}
该方法是一个线程安全的方法,通过该方法添加的监听器,都存储在Application的mActivityLifecycleCallbacks这一ArrayList中。那么callbacks的对应方法又是在何时调用的呢?答案就在Activity中。以onActivityCreated()回调为例:
protected void onCreate(@Nullable Bundle savedInstanceState) {
// ...省略一段代码
mFragments.dispatchCreate();
getApplication().dispatchActivityCreated(this, savedInstanceState);
if (mVoiceInteractor != null) {
mVoiceInteractor.attachActivity(this);
}
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
}
关键就在这一行getApplication().dispatchActivityCreated(this, savedInstanceState);。通过查看源码我们发现,Application中一一声明了与ActivityLifecycleCallbacks中方法对应的dispatchActivityXXX()方法,以Application#dispatchActivityCreated()为例:
void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
savedInstanceState);
}
}
}
Application会遍历这一时刻添加的所有ActivityLifecycleCallbacks并回调对应的生命周期方法。同时我们也发现,这一方式无法做到在Activity的声明周期调用之前做一些事情,因为回调生在在supert.onXXX()中。
##b.添加Fragment回调
FragmentManager#registerFragmentlifecyclecallbacks()这一API是在support library version 25.1.0中添加的。我们可以通过传递一个``类的实现类以及一个boolean类型的变量来实现生命周期的监听,该抽象类声明如下:
public abstract static class FragmentLifecycleCallbacks {
public void onFragmentPreAttached(@NonNull FragmentManager fm, @NonNull Fragment f,
@NonNull Context context) {}
public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f,
@NonNull Context context) {}
public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f,
@Nullable Bundle savedInstanceState) {}
public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f,
@Nullable Bundle savedInstanceState) {}
public void onFragmentActivityCreated(@NonNull FragmentManager fm, @NonNull Fragment f,
@Nullable Bundle savedInstanceState) {}
public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f,
@NonNull View v, @Nullable Bundle savedInstanceState) {}
public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentSaveInstanceState(@NonNull FragmentManager fm, @NonNull Fragment f,
@NonNull Bundle outState) {}
public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) {}
public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) {}
}
值得注意的是,相比Application的方法相比,FragmentManager的方法多了一个参数:boolean recursive,如果该参数为true,则会为所有子孙Fragment也注册回调。
首先,Fragment的生命周期由FragmentManager通过moveToState()方法调用。同样,这里以onFragmentCreated为例,其调用流程如下:
moveToState() -> dispatchOnFragmentCreated(),dispatchOnFragmentCreated()代码:
void dispatchOnFragmentCreated(@NonNull Fragment f, @Nullable Bundle savedInstanceState,
boolean onlyRecursive) {
// ...省略一段代码
// 遍历callback回调声明周期方法
for (FragmentLifecycleCallbacksHolder holder : mLifecycleCallbacks) {
if (!onlyRecursive || holder.mRecursive) {
holder.mCallback.onFragmentCreated(this, f, savedInstanceState);
}
}
}
到这里我们可以发现,与ActivityLifecycleCallbacks一样,这一方式同样在onXXX()方法之后进行。
综上所属,这种方式的优缺点如下:
###优点:
- 可以统一监听所有Activity/Fragment,方便管理。
- 不侵入已有代码,耦合性较低。
- 而且可以操作第三方Activity/Fragment的声明周期。
###缺点:仅能在相应周期回调后操作,是这一方法唯一的缺点。
#3.BaseActivity/BaseFragment
这一方法就是实现一个基类Activity/Fragment,在里面实现一些通用的方法,让项目中的activity都继承它,来达到封装的目的。但是该方法缺点也很明显,由于Java的继承机制只允许一个类拥有唯一父类,所以该方法无法用于第三方框架也使用该方式的场景,并且侵入性强。
#4.实现
LifecycleObserver该方法是支持库中的类,现已嵌入androidX包中。该接口声明如下:
public interface LifecycleObserver {}
可以看到,这就是一个空接口,他的意义就是标记类,因为仅仅实现该方法并不能监控任何生命周期回调。为了监控生命周期,我们还需要配合@OnLifecycleEvent注解一同食用:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OnLifecycleEvent {
Lifecycle.Event value();
}
该注解接收一个Lifecycle.Event类型的参数,这是一个枚举类,声明了可以监控到的生命周期变更事件:
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
其中值得说明的是ON_ANY,该值表示任何变更事件都将回调。完整的例子如下:
class LifecycleListener: LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onStateChanged(owner:LifecycleOwner,event:Lifecycle.Event){
Log.e("LifecycleListener","owner $owner,event $event")
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onStateChanged(owner:LifecycleOwner){
Log.e("LifecycleListener","owner $owner")
}
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
fun onStateChanged(){
Log.e("LifecycleListener","called")
}
}
需要注意两点:
- 实现
LifecycleObserver的类,必须拥有一个无参的构造函数; @OnLifecycleEvent注解的方法,参数可以有0-2个,其中1-2的参数类型,必须按如上声明,否则会报错(因为系统只会按照上述顺序传参) 接下来还有最后一步:注册观察者!
class TestActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// 添加Observer
lifecycle.addObserver(LifecycleListener())
}
}
###ps:Fragment与Activity使用方式相同
这一步是通过调用Lifecycle#addObserver()实现的,对于ComponentActivity而言,实际调用的是LifecycleRegistry#addObserver()方法。
##优点:
- 侵入性低
- 使用灵活 ##缺点:
- 可监控生命周期种类较少
- 无法对第三方Activity/Fragment直接使用 下面让我们来分析一下,这一方式是如何实现的! Lifecycle组件的实现原理