Activity启动过程之生命周期方法回调分析

在之前的文章Activity启动过程分析Hook一个Activity的启动过程中均分析了Activity的启动过程,不过前者的分析侧重点在AMS这块,而后者侧重寻找启动过程的Hook点。

而本文要分析一下Activity的具体创建过程和需要关注的一些地方,这也为了理解插件化机制打下一个好的基础。AMS通过Binder调用ApplicationThread的scheduleLaunchActivity方法,我们就以这个方法开始分析。

scheduleLaunchActivity方法中的第2个参数,还记得我们上文Hook一个Activity的启动过程讲的吗,这个token就是用于标示Activity启动相关的一个记录,AMS就是通过这个token来控制Activity的生命周期方法的调用,ActivityThread这端就是通过token来获取对应的ActivityClientRecord,进而对对应的Activity进行操作。

# android.app.ActivityThread$ApplicationThread
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
                                         ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
                                         CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
                                         int procState, Bundle state, PersistableBundle persistentState,
                                         List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
                                         boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {

    updateProcessState(procState, false);

    ActivityClientRecord r = new ActivityClientRecord();

    r.token = token;
    r.ident = ident;
    r.intent = intent;
    ...
    sendMessage(H.LAUNCH_ACTIVITY, r);
}

ApplicationThread的scheduleLaunchActivity方法是在Binder线程池中调用,所以通过发送一个H.LAUNCH_ACTIVITY的消息通过H 和这个Hander来切换到主线程,在其handleMessage方法中会调用ActivityThread的handleLaunchActivity方法。注意在此之前调用了ActivityThread的getPackageInfoNoCheck方法,该方法用于获取一个LoadedApk对象。

public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case LAUNCH_ACTIVITY: {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
            final ActivityClientRecord r = (ActivityClientRecord) msg.obj;

            r.packageInfo = getPackageInfoNoCheck(
                    r.activityInfo.applicationInfo, r.compatInfo);
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        break;
      ...
    }
}

LoadedApk对象的注释是这样的:

Local state maintained about a currently loaded .apk.

意思就是LoadedApk表示的是当前被加载的Apk文件对应的一个数据对象。
getPackageInfoNoCheck方法这里我们先不介绍,回头再介绍插件化相关知识的时候再来说明。

接下来看一下ActivityThread的handleLaunchActivity方法,在该方法中主要干了两件事,一件是调用performLaunchActivity方法创建Activity,attach上下文,并执行Activity的onCreate、onStart、onRestoreInstanceState等方法。在handleResumeActivity方法中回调Activity的onResume方法。

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);

    if (a != null) {
        r.createdConfig = new Configuration(mConfiguration);
        reportSizeConfigurations(r);
        Bundle oldState = r.state;
        handleResumeActivity(r.token, false, r.isForward,
                !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
        ...
    } else {
       ...
    }
}

先来看一下performLaunchActivity方法,先从ActivityClientRecord获取ActivityInfo,这个ActivityInfo表示的就是在AndroidManifest.xml中一个activity标签所代表的Activity信息。r.packageInfo 表示的是LoadedApk对象,如果该对象为null就会调用一个public的getPackageInfo方法来获取LoadedApk,还记得我们之前说的getPackageInfoNoCheck方法吗,其实他们最终都是调用一个private的getPackageInfo方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");

// ActivityInfo表示的就是在AndroidManifest.xml中一个activity标签所代表的Activity信息。
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }

// 在该方法中,下面这段代码表示的是如果是隐式调用,需要通过PackageManager来进行解析,获取正确的跳转对象。
    ComponentName component = r.intent.getComponent();
    if (component == null) {
        component = r.intent.resolveActivity(
                mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }

    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }

    Activity activity = null;
    try {
      // 通过LoadedApk中的ClassLoader来创建Activity
        java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
        StrictMode.incrementExpectedActivityCount(activity.getClass());
        r.intent.setExtrasClassLoader(cl);
        r.intent.prepareToEnterProcess();
        if (r.state != null) {
            r.state.setClassLoader(cl);
        }
    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                    "Unable to instantiate activity " + component
                            + ": " + e.toString(), e);
        }
    }

    try {
       // 通过LoadedApk来穿件Application对象
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);

        if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
        if (localLOGV) Slog.v(
                TAG, r + ": app=" + app
                        + ", appName=" + app.getPackageName()
                        + ", pkg=" + r.packageInfo.getPackageName()
                        + ", comp=" + r.intent.getComponent().toShortString()
                        + ", dir=" + r.packageInfo.getAppDir());

        if (activity != null) {
            // 实际上创建的是ComtextImpl对象
            Context appContext = createBaseContextForActivity(r, activity);
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                    + r.activityInfo.name + " with config " + config);
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            // 调用attach方法,关联一些必要的对象,比如创建Window对象,绑定上下文等
            activity.attach(appContext, this, getInstrumentation(), r.token,
                    r.ident, app, r.intent, r.activityInfo, title, r.parent,
                    r.embeddedID, r.lastNonConfigurationInstances, config,
                    r.referrer, r.voiceInteractor, window);

            if (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            activity.mStartedActivity = false;
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }

            activity.mCalled = false;
            // 调用Instrumentation的callActivityOnCreate方法,会回调Activity的onCreate方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            if (!activity.mCalled) {
                throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                                " did not call through to super.onCreate()");
            }
            r.activity = activity;
            r.stopped = true;
          // 如果还没有调用Finish方法,就接着调用Activity的performStart方法,其实还是通过Instrumentation来调用Activity的onStart方法
            if (!r.activity.mFinished) {
                activity.performStart();
                r.stopped = false;
            }

         // 如果还没有调用Finish方法,就接着调用Instrumentation的callActivityOnRestoreInstanceState方法,会回调Activity的onRestoreInstanceState方法
            if (!r.activity.mFinished) {
                if (r.isPersistable()) {
                    if (r.state != null || r.persistentState != null) {
                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                                r.persistentState);
                    }
                } else if (r.state != null) {
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
                }
            }
           // 如果还没有调用Finish方法,就接着调用Instrumentation的callActivityOnPostCreate方法,会回调Activity的onPostCreate方法
            if (!r.activity.mFinished) {
                activity.mCalled = false;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state,
                            r.persistentState);
                } else {
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);
                }
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                            "Activity " + r.intent.getComponent().toShortString() +
                                    " did not call through to super.onPostCreate()");
                }
            }
        }
        r.paused = true;
        
        // 到这里把token和对应的ActivityClientRecord放在ArrayMap mActivities中
        mActivities.put(r.token, r);

    } catch (SuperNotCalledException e) {
        throw e;

    } catch (Exception e) {
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                    "Unable to start activity " + component
                            + ": " + e.toString(), e);
        }
    }

    return activity;
}

上面我们在注释中大致讲了一下Activity的创建流程,下面我们来关注一下细节,Instrumentation通过调用newActivity方法来创建Activity,我们来看一下这个方法干了什么。代码很简单,就是通过ClassLoader去加载Class并创建对象。注意这个ClassLoader是从LoadedApk中获取的。这个LoadedApk表示的是当前正在运行的App。

那么我们在这里想一想,如果要加载一个未安装的Apk,该怎么去加载呢,可不可以想办法构造一个未安装的Apk对应的LoadedApk对象,并让它的ClassLoader变为DexClassLoader,而DexClassLoader是可以加载一个未安装的Apk文件中的dex的,这样不就可以实现一个加载未安装Apk中的代码了吗。

# android.app.Instrumentation
public Activity newActivity(ClassLoader cl, String className,
                            Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}

下面我们接着分析,创建完Activity对象之后,会调用LoadedApk的makeApplication方法来创建一个Application对象,看一下这个方法。首先Application如果已经创建过的话会赋值给mApplication变量,那么就直接返回mApplication。然后还需要判断需要创建哪个Application对象,如果我们App中没有指定Application,就直接创建android.app.Application对象。如果自定义了Application,就创建指定的对象。

public Application makeApplication(boolean forceDefaultAppClass,
                                   Instrumentation instrumentation) {
    // 如果已经创建过,直接返回
    if (mApplication != null) {
        return mApplication;
    }
   ...
    // 根据条件判断创建哪个Application对象
    Application app = null;
    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }

    // 也是通过LoadedApk中的ClassLoader来创建Application
    try {
        java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    "initializeJavaContextClassLoader");
            // 如果包名不是android,还需要初始化上下文ClassLoader
            initializeJavaContextClassLoader();
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        }
        // 创建ContextImpl对象
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        // 调用Instrumentation的newApplication方法来创建Application对象
        app = mActivityThread.mInstrumentation.newApplication(
                cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
       ...
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;

    if (instrumentation != null) {
        try {
          // 调用Instrumentation的callApplicationOnCreate方法,会回调Application的onCreate方法
            instrumentation.callApplicationOnCreate(app);
        } catch (Exception e) {
         ...
        }
    }
  ...
    return app;
}

Instrumentation的newApplication方法,最后会调用到它的一个静态的newApplication方法,我们来看一下。就是根据传递的className,来创建Application对象,创建完对象之后,还会调用Application的attach方法,在attach方法中会调用attachBaseContext方法,而该方法也是我们应用开发层面能够最早接收到Application的一个回调方法,所以像MultiDex等都要在这个方法中调用比较合适。


public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return newApplication(cl.loadClass(className), context);
}

static public Application newApplication(Class<?> clazz, Context context)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    Application app = (Application)clazz.newInstance();
    app.attach(context);
    return app;
}

final void attach(Context context) {
    attachBaseContext(context);
    mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}

在performLaunchActivity中,当创建完Activity对象和拿到Application对象之后,调用createBaseContextForActivity方法返回一个Context对象,该对象实际上是一个ContextImpl对象。后面会调用Activity的attach方法,这个方法很重要,调用了attachBaseContext方法,设置Activity的baseContext为ContextImpl对象。创建了Window对象并设置Callback为当前的Activity对象,因此Activity可以接收到Window的回调,并且Window对象设置了WindowManager。拿到ActivityThread和Instrumentation的引用,需要说明的是,在整个App进程中,只有一个ActivityThread和Instrumentation对象,所有的Activity中拿到的都是同一个引用。在这个方法中也可以看到,Activity拿到了表示它自身的一个IBinder对象 token。

# android.app.Activity
final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                  Window window) {
    attachBaseContext(context);

    mFragments.attachHost(null /*parent*/);

    mWindow = new PhoneWindow(this, window);
    mWindow.setWindowControllerCallback(this);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    mUiThread = Thread.currentThread();

    mMainThread = aThread;
    mInstrumentation = instr;
    mToken = token;
    mIdent = ident;
    mApplication = application;
    mIntent = intent;
    mReferrer = referrer;
    mComponent = intent.getComponent();
    mActivityInfo = info;
    mTitle = title;
    mParent = parent;
    mEmbeddedID = id;
    mLastNonConfigurationInstances = lastNonConfigurationInstances;
    if (voiceInteractor != null) {
        if (lastNonConfigurationInstances != null) {
            mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;
        } else {
            mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,
                    Looper.myLooper());
        }
    }

    mWindow.setWindowManager(
            (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
            mToken, mComponent.flattenToString(),
            (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
}

Activity的attach方法调用之后,紧接着调用了Instrumentation的callActivityOnCreate方法,我们只看两个参数的就好了。

# android.app.Instrumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

在callActivityOnCreate方法中又调用了Activity的performCreate方法,在performCreate方法中又调用了Activity自身的onCreate方法,在onCreate方法中会把mCalled设置为true。

# android.app.Activity
final void performCreate(Bundle icicle) {
    restoreHasCurrentPermissionRequest(icicle);
    onCreate(icicle);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

protected void onCreate(@Nullable Bundle savedInstanceState) {
    if (DEBUG_LIFECYCLE) Slog.v(TAG, "onCreate " + this + ": " + savedInstanceState);
    if (mLastNonConfigurationInstances != null) {
        mFragments.restoreLoaderNonConfig(mLastNonConfigurationInstances.loaders);
    }
    if (mActivityInfo.parentActivityName != null) {
        if (mActionBar == null) {
            mEnableDefaultActionBarUp = true;
        } else {
            mActionBar.setDefaultDisplayHomeAsUpEnabled(true);
        }
    }
    if (savedInstanceState != null) {
        Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
        mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.fragments : null);
    }
    mFragments.dispatchCreate();
    getApplication().dispatchActivityCreated(this, savedInstanceState);
    if (mVoiceInteractor != null) {
        mVoiceInteractor.attachActivity(this);
    }
    mCalled = true;
}

在Activity生命周期方法中,任何一个方法都可能调用finish来结束。所以,在执行onStart、onRestoreInstanceState、onPostCreate等之前,都会判断是否结束了。根据的就是Activity的一个变量mFinished,当Activity中调用finish方法,该变量会为true。后面的生命周期方法就不会再执行了。

在performLaunchActivity方法中其它生命周期方法的回调也很简单,这里就不多讲了,有兴趣的可以自行查看。我们只需要记住一些关键过程就好了。

下面来分析一下ActivityThread的handleResumeActivity方法,该方法先根据传递的参数token来获取对应的ActivityClientRecord,之后就会调用performResumeActivity方法,注意这个返回值是ActivityClientRecord对象,相当于要更新这个记录。

final void handleResumeActivity(IBinder token,
                                boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (!checkAndUpdateLifecycleSeq(seq, r, "resumeActivity")) {
        return;
    }

    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    // TODO Push resumeArgs into the activity for consideration
    r = performResumeActivity(token, clearHide, reason);

  ...
    return r;
}

我们再来看一下performResumeActivity方法,在该方法中如果ActivityClientRecord 的pendingIntents不为null,就会调用 deliverNewIntents(r, r.pendingIntents) ,最终会回调Activity的onNewIntent方法。后面r.activity.performResume()会调用到Activity的performResume方法。

public final ActivityClientRecord performResumeActivity(IBinder token,
                                                        boolean clearHide, String reason) {
    ActivityClientRecord r = mActivities.get(token);
    if (localLOGV) Slog.v(TAG, "Performing resume of " + r
            + " finished=" + r.activity.mFinished);
    if (r != null && !r.activity.mFinished) {
        if (clearHide) {
            r.hideForNow = false;
            r.activity.mStartedActivity = false;
        }
        try {
            r.activity.onStateNotSaved();
            r.activity.mFragments.noteStateNotSaved();
            if (r.pendingIntents != null) {
                // 回调Activity的onNewIntent方法
                deliverNewIntents(r, r.pendingIntents);
                r.pendingIntents = null;
            }
            if (r.pendingResults != null) {
                deliverResults(r, r.pendingResults);
                r.pendingResults = null;
            }
            // 调用Activity的performResume方法
            r.activity.performResume();

            // If there is a pending local relaunch that was requested when the activity was
            // paused, it will put the activity into paused state when it finally happens.
            // Since the activity resumed before being relaunched, we don't want that to happen,
            // so we need to clear the request to relaunch paused.
            for (int i = mRelaunchingActivities.size() - 1; i >= 0; i--) {
                final ActivityClientRecord relaunching = mRelaunchingActivities.get(i);
                if (relaunching.token == r.token
                        && relaunching.onlyLocalRequest && relaunching.startsNotResumed) {
                    relaunching.startsNotResumed = false;
                }
            }

            EventLog.writeEvent(LOG_AM_ON_RESUME_CALLED, UserHandle.myUserId(),
                    r.activity.getComponentName().getClassName(), reason);

            r.paused = false;
            r.stopped = false;
            r.state = null;
            r.persistentState = null;
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException(
                        "Unable to resume activity "
                                + r.intent.getComponent().toShortString()
                                + ": " + e.toString(), e);
            }
        }
    }
    return r;
}

在Activity的performResume方法中会执行performRestart方法,但是也是通过Instrumentation来执行具体的onRestart、onStart方法,不过该方法执行的前提是已经执行了onStop方法。这里面没有什么难点,无非就是通过Instrumentation执行Activity的生命周期方法,后面接着会执行onResume、onPostResume方法。

# android.app.Activity
final void performResume() {
    performRestart();

    mFragments.execPendingActions();

    mLastNonConfigurationInstances = null;

    mCalled = false;
    // mResumed is set by the instrumentation
    mInstrumentation.callActivityOnResume(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                        " did not call through to super.onResume()");
    }

    // invisible activities must be finished before onResume() completes
    if (!mVisibleFromClient && !mFinished) {
        Log.w(TAG, "An activity without a UI must call finish() before onResume() completes");
        if (getApplicationInfo().targetSdkVersion
                > android.os.Build.VERSION_CODES.LOLLIPOP_MR1) {
            throw new IllegalStateException(
                    "Activity " + mComponent.toShortString() +
                            " did not call finish() prior to onResume() completing");
        }
    }

    // Now really resume, and install the current status bar and menu.
    mCalled = false;

    mFragments.dispatchResume();
    mFragments.execPendingActions();

    onPostResume();
    if (!mCalled) {
        throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                        " did not call through to super.onPostResume()");
    }
}

我们继续来分析ActivityThread的handleResumeActivity方法,执行完performResumeActivity方法之后,还有一部分主要用于处理Window的,从Window中取出DecorView,并且调用WindowManager的addView方法,这个具体的调用时通过WindowManager的实现类WindowManagerImpl,实际上这个它也是个不干事的,会继续委托给WindowManagerGlobal来处理,最终会创建ViewRootImpl,并触发整个View视图的绘制流程,这里过程在这里就不详细分析了。不过我们从这个也可以看出,当Activity的onResume方法执行之后,才会开始触发整个View的绘制流程,也就是说实际上在onResume方法中我们是无法获取View的宽高的。在Activity的onWindowFocusChanged方法中如果参数为true,表明Actvity中的视图全部绘制完毕,可以正确的拿到宽高。

final void handleResumeActivity(IBinder token,
                                boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
    ActivityClientRecord r = mActivities.get(token);
 ...
    r = performResumeActivity(token, clearHide, reason);

    if (r != null) {
        final Activity a = r.activity;

        if (localLOGV) Slog.v(
                TAG, "Resume " + r + " started activity: " +
                        a.mStartedActivity + ", hideForNow: " + r.hideForNow
                        + ", finished: " + a.mFinished);

        final int forwardBit = isForward ?
                WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            try {
                willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                        a.getActivityToken());
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient && !a.mWindowAdded) {
                a.mWindowAdded = true;
                wm.addView(decor, l);
            }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(
                    TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r, false /* force */);

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible
                && r.activity.mDecor != null && !r.hideForNow) {
            if (r.newConfig != null) {
                performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                        + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig);
                r.newConfig = null;
            }
            if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                    + isForward);
            WindowManager.LayoutParams l = r.window.getAttributes();
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    wm.updateViewLayout(decor, l);
                }
            }
            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }

        if (!r.onlyLocalRequest) {
            r.nextIdle = mNewActivities;
            mNewActivities = r;
            if (localLOGV) Slog.v(
                    TAG, "Scheduling idle handler for " + r);
            Looper.myQueue().addIdleHandler(new Idler());
        }
        r.onlyLocalRequest = false;

        // Tell the activity manager we have resumed.
        if (reallyResume) {
            try {
                ActivityManagerNative.getDefault().activityResumed(token);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }

    } else {
        // If an exception was thrown when trying to resume, then
        // just end this activity.
        try {
            ActivityManagerNative.getDefault()
                    .finishActivity(token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
}

Activity的生命周期方法回调就分析到这里了,在这里我们可以做一下小结:

  • Application和Activity都是通过LoadedApk中的ClassLoader以及className创建。
  • LoadedApk对象是根据ActivityThread的getPackageInfo方法创建
  • Application和Activity都要attach一个ContextImpl对象。
  • 在Activity的attach方法中会创建Window对象,也就是说一个Activity对应一个Window对象。
  • onResume方法之后才开始View视图的绘制
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容