Activity A启动B后生命周期变化

198 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

当A Activity启动B Activity后,其生命周期如何变化呢?我们沿用前文中Hook Instrumentation的方案来看下,在Activity互相跳转时,其生命周期如何变化,修改MyCustomInstrumentation,如下所示:

 public class CustomInstrumentation extends Instrumentation {
     private static final String TAG = "CustomInstrumentation";
     private Instrumentation mBaseInstrumentation;
 ​
     public CustomInstrumentation(Instrumentation instrumentation) {
         super();
         mBaseInstrumentation = instrumentation;
     }
 ​
     @Override
     public void callActivityOnCreate(Activity activity, Bundle icicle) {
         super.callActivityOnCreate(activity, icicle);
         Log.d(TAG, "callActivityOnCreate " + activity.toString());
     }
 ​
     @Override
     public void callActivityOnStart(Activity activity) {
         super.callActivityOnStart(activity);
         Log.d(TAG, "callActivityOnStart " + activity.toString());
     }
 ​
     @Override
     public void callActivityOnResume(Activity activity) {
         super.callActivityOnResume(activity);
         Log.d(TAG, "callActivityOnResume " + activity.toString());
     }
 ​
     @Override
     public void callActivityOnPause(Activity activity) {
         super.callActivityOnPause(activity);
         Log.d(TAG, "callActivityOnPause " + activity.toString());
     }
 ​
     @Override
     public void callActivityOnStop(Activity activity) {
         super.callActivityOnStop(activity);
         Log.d(TAG, "callActivityOnStop " + activity.toString());
     }
 ​
     @Override
     public void callActivityOnDestroy(Activity activity) {
         super.callActivityOnDestroy(activity);
         Log.d(TAG, "callActivityOnDestroy " + activity.toString());
     }
 ​
     public Activity newActivity(ClassLoader cl, String className,
                                 Intent intent)
             throws InstantiationException, IllegalAccessException,
             ClassNotFoundException {
         Log.d(TAG, "newActivity: " + className);
         return mBaseInstrumentation.newActivity(cl, className, intent);
     }
 }

启动普通的Activity

在MainActivity中以startActivity方式启动NotifyAcLifecycleActivity,启动后不finish MainActivity,此时CustomInstrumentation打印的日志如下:

2-1-3-11

从日志可以看出当MainActivity启动NotifyAcLifecycleActivity时,生命周期变化如下图所示:

AStartBLifecycle.drawio

启动Dialog样式或者Translucent的Activity

新建DialogActivity,指定其Theme为Theme.AppCompat.Dialog,随后在MainActivity中启动DialogActivity,此时CustomInstrumentation打印的日志如下:

2-1-3-12

可以看出,当DialogActivity onResume执行后,MainActivity并没有执行onStop方法,仍然处于pause状态,进而我们可以总结出:

  • A Activity启动非Dialog样式的Activity后,A先pause,随后B进入resume状态后,A调用onStop
  • A Activity启动Dialog样式的Activity后,A先pause,随后B进入resume状态

从上述结论,我们不难推断onStop设计的意图是当Activity对用户完全不可见时回调,接下来我们来看下源码中onStop的说明:

 /**
  * Called when you are no longer visible to the user.  You will next
  * receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
  * depending on later user activity. This is a good place to stop
  * refreshing UI, running animations and other visual things.
  *
  * <p><em>Derived classes must call through to the super class's
  * implementation of this method.  If they do not, an exception will be
  * thrown.</em></p>
  *
  * @see #onRestart
  * @see #onResume
  * @see #onSaveInstanceState
  * @see #onDestroy
  */
 @CallSuper
 protected void onStop() {
     ......
 }

从其方法注释上也能看到该说明,onStop method Called when you are no longer visible to the user. 同样的我们也可以看到onPause的函数说明中关于其调用时机的介绍,当当前页面不再参与用户交互时,会回调该方法,Called as part of the activity lifecycle when the user no longer actively interacts with the activity, but it is still visible on screen. The counterpart to onResume.

重新梳理Activity各声明周期函数回调时机如下图所示:

ActivityLifecycleExplain.drawio

在onCreate中直接调用finish,会出现onCreate,onResume,onDestroy序列的生命周期现象