深入理解Android生命周期

(借鉴自Android开发艺术探索)


正常情况


onCreate

表示Activity正在被创建

onRestart

表示Activity正在被重新启动,一般当Activity从不可见到可见,这个方法会被调用

onStart

表示Activity正在被启动,这个时候Activity的界面已经有了(可以认为是可见了,只不过还没有让用户看到)

onResume

表示Activity已经完全可见了

onPause

表示Activity正在停止

onStop

表示Activity即将停止

onDestory

表示Activity即将被销毁,这里适合做一些回收工作




其实onPause执行了,这个时候Activity是部分可见的(比如dialog调用后,Activity会处于onPause状态),当你打开一个新的Activity,正常情况下原来的Activity的onPause和onStop会被调用,但是如果说这个新的Activity是透明的话,原来的Activity只会调用onPause,而不会调用onStop。


启动Activity的请求由Instrumentation来处理,然后Instrumentation通过binder向ActivityManagerService发送请求。ActivityManagerService内部维护一个ActivityStack并负责栈内的Activity的状态同步。AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用。


看一下ActivityStack的resumeTopActivityInnerLocked方法

// We need to start pausing the current activity so the top one can be resumed...
final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, next, dontWaitForPause);
if (mResumedActivity != null) {
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityLocked: Pausing " + mResumedActivity);
    pausing |= startPausingLocked(userLeaving, false, next, dontWaitForPause);
}
startPausingLocked是停止当前处于Resume状态的Activity的方法。所以我们得知,当当前栈顶的Activity执行onPause方法后,新的Activity才可以启动。


为什么说只有在当前栈顶的Activity执行onPause方法后,新的Activity才可以启动呢?我们可以找一下整个流程最后部分的代码。

app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
        System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
        new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage,
        task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
        newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
这里的thread查得是IApplicationThread(ActivityThread的子类),而ActivityThread的scheduleLaunchActivity方法最终会完成新Activity的onCreate、onStart、onResume的调用。所以我们得出了上面这个结论: 只有在当前栈顶的Activity执行onPause方法后,新的Activity才可以启动


看一下scheduleLaunchActivity方法最终调用的handleLaunchActivity方法

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    // If we are getting ready to gc after going to the background, well
    // we are back active so skip it.
    unscheduleGcIdler();
    mSomeActivitiesChanged = true;

    if (r.profilerInfo != null) {
        mProfiler.setProfiler(r.profilerInfo);
        mProfiler.startProfiling();
    }

    // Make sure we are running with the most recent config.
    handleConfigurationChanged(null, null);

    if (localLOGV) Slog.v(
        TAG, "Handling launch of " + r);

    // Initialize before creating the activity
    WindowManagerGlobal.initialize();

    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);
Activity a = performLaunchActivity(r, customIntent);这一行完成了Activity的创建


再看看performLaunchActivity方法

Activity activity = null;
try {
    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);
    }
}
调用了mInstrumentation.newActivity方法利用反射机制创建了Activity(通过类名获取类,再newInstance即可)

public Activity newActivity(ClassLoader cl, String className,
        Intent intent)
        throws InstantiationException, IllegalAccessException,
        ClassNotFoundException {
    return (Activity)cl.loadClass(className).newInstance();
}
沿着performLaunchActivity方法继续往下看

activity和window建立联系(类似于碎片和activity建立联系,其实就是入栈)

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 (theme != 0) {
    activity.setTheme(theme);
}
回调Activity的onCreate

activity.mCalled = false;
if (r.isPersistable()) {
    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
    mInstrumentation.callActivityOnCreate(activity, r.state);
}
调用Activity的onStart(performStart最后也会回调mInstrumentationActivity的onStart)

if (!r.activity.mFinished) {
    activity.performStart();
    r.stopped = false;
}
看一下Activiy类中的performStart中有一段天杀的代码,运行失败的dialog!(得知了这个是在onStart时出现的)

if (isAppDebuggable) {
      new AlertDialog.Builder(this).
          setTitle(appName).
          setMessage(warning).
          setPositiveButton(android.R.string.ok, null).
          setCancelable(false).
          show();
} else {
    Toast.makeText(this, appName + "\n" + warning, Toast.LENGTH_LONG).show();
}

除此以外,还有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);
    }
}
还有ActivityOnPostCreate的调用

if (r.isPersistable()) {
    mInstrumentation.callActivityOnPostCreate(activity, r.state,
            r.persistentState);
} else {
    mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
performLaunchActivity到这里就没了,这个方法里调用了Activity的onCreate和onStart。而onResume方法要回到handleLaunchActivity方法里继续看。

handleLaunchActivity方法

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);
就在performLaunchActivity方法的调用下面的一点点。调用了handleResumeActivity方法,在这里调用Activity的onResume。


到这里就找到了onCreate,onStart,onResume了。知道这些流程就已经可以应付大大小小的场合了。(如果感兴趣可以再完全地看一遍更多相关的代码,很好找,也很有趣,也看得懂。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值