Android源码分析之Activity的启动流程


说明:本文是基于Android6.0源码来分析的


  本文只是从源码的角度分析Activity的启动流程,并不会介绍Activity本身的一些特点,比如如何创建Activity,如何开启一个新的Activity,Activty的生命周期,启动模式等;如果你是一个刚入门的Android开发,这篇文章可能对你来说有些晦涩难懂,如果你是一个老猿并且想对Activity的启动流程又一个比较直观的了解,这片文章或许能够帮助你。

  由于Activity的启动会根据不同的状态,不同的启动模式,是否在一个应用内部启动一个Activity等不同情况而不同,如果都考虑进来可能会比较繁琐,不利于掌握和分析,所以我们就以一个Activty的启动模式是standard的标准模式并且是在同一个应用里面且不带Bundle参数的情况下来分析,下面我们就正式进入分析的流程。

  一般我们开启一个Activity都是从startActivity方法开始的

 public void startActivity(Intent intent) {
        this.startActivity(intent, null);
    }

接着接着调用Activity中的带两个参数的startActivity方法

@Override
    public void startActivity(Intent intent, @Nullable Bundle options) {
        if (options != null) {
            startActivityForResult(intent, -1, options);
        } else {
            // Note we want to go through this call for compatibility with
            // applications that may have overridden the method.
            startActivityForResult(intent, -1);
        }
    }

option是null,所有会走else里的逻辑

 public void startActivityForResult(Intent intent, int requestCode) {
        startActivityForResult(intent, requestCode, null);
    }

首次开启mParent == null,所以走if里面的逻辑,由于startActivityForResult的代码有点多,所以我只贴我们关注的部分代码

public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (mParent == null) {
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);
            if (ar != null) {
                mMainThread.sendActivityResult(
                    mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                    ar.getResultData());
            }
            ...
        }
    }

如果想了解Instrumentation这个类,可以看一下这片文章的介绍Instrumentation的介绍;Now接着我们的Activity的启动流程继续分析,调用Instrumentation#execStartActivity

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
                ...
                try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess();
            int result = ActivityManagerNative.getDefault()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
            checkStartActivityResult(result, intent);
        } catch (RemoteException e) {
            throw new RuntimeException("Failure from system", e);
        }
                ...
            }

我们看到是通过 ActivityManagerNative.getDefault()来启动的,那么getDefault()是什么呢?

 static public IActivityManager getDefault() {
        return gDefault.get();
    }
    
    private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
    };

其实就是在获取ActivityManagerServer。
IActivityManager是个接口,ActivityManagerNative是一个IActivityManager是接口的一个抽象实现类,ActivityManagerService又是ActivityManagerNative的一个具体的实现类。所以最终调用的是,ActivityManagerService#startActivity()方法。

 @Override
    public final int startActivity(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, options,
            UserHandle.getCallingUserId());
    }

    @Override
    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
        enforceNotIsolatedCaller("startActivity");
        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
                false, ALLOW_FULL_ONLY, "startActivity", null);
        // TODO: Switch to user app stacks here.
        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, options, false, userId, null, null);
    }

就是不断的调用ActivityManagerService的重载方法,然后再调用ActivityStackSupervisor#startActivityMayWait方法。

 final int startActivityMayWait(IApplicationThread caller, int callingUid,
            String callingPackage, Intent intent, String resolvedType,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int startFlags,
            ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
            Bundle options, boolean ignoreTargetSecurity, int userId,
            IActivityContainer iContainer, TaskRecord inTask) {
                ...
                
            int res = startActivityLocked(caller, intent, resolvedType, aInfo,
                    voiceSession, voiceInteractor, resultTo, resultWho,
                    requestCode, callingPid, callingUid, callingPackage,
                    realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
                    componentSpecified, null, container, inTask);
                ...
                
            }

然后又调用了重载的startActivityLocked(),这个方法真的是和老太太的脚一样,又臭又长啊,但是重点就在这个方法最后面

final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            ActivityContainer container, TaskRecord inTask) {
                ...
                 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
                ...
            }

结合调用了startActivityUncheckedLocked(),这个方法其实也不简单,也是很长,逻辑很多,但是重要的方法也是在最后几行调用的。

final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
                ...
                targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
                ...
            }

接着调用了ActivityStack#startActivityLocked方法,怎么说呢,这个方法也会比较长的,但是相较于前面的两个方法,这个方法还是比较端的,我们只贴关键代码

final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
                ...
                 if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
                ...
            }

接着调用了ActivityStack#resumeTopActivitiesLocked方法

 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
                ...
                   if (!addingToTask && reuseTask == null) {
                        // We didn't do anything...  but it was needed (a.k.a., client
                        // don't use that intent!)  And for paranoia, make
                        // sure we have correctly resumed the top activity.
                          //重点方法 
                        if (doResume) {
                          targetStack.resumeTopActivityLocked(null, options);
                            if (!movedToFront) {
                                // Make sure to notify Keyguard as well if we are not running an app
                                // transition later.
                                notifyActivityDrawnForKeyguard();
                            }
                        } else {
                            ActivityOptions.abort(options);
                        }
                        return ActivityManager.START_TASK_TO_FRONT;
                    }
                ...
            }

接着调用了ActivityStack#resumeTopActivityLocked方法


    final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }

接着调用resumeTopActivityInnerLocked方法,这个方法也很长。

 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
     ...
      mStackSupervisor.startSpecificActivityLocked(next, true, true);
     ...
 }

接着调用ActivityStackSupervisor#startSpecificActivityLocked方法,这个方法还是比较重要的,里面有行代码还是很重要的,那就是 mService.startProcessLocked方法,这个方法就是开启一个新app的时候创建新进程的方法,这个不展开了,后面会写一片Android应用的启动流程,就会设计到这里了。

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
                ...
          
        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                        || !"android".equals(r.info.packageName)) {
                    // Don't add this if it is a platform component that is marked
                    // to run in multiple processes, because this is actually
                    // part of the framework so doesn't make sense to track as a
                    // separate apk in the process.
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                            mService.mProcessStats);
                }
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
                ...
    }

这里调用的就是ActivityStackSupervisor#realStartActivityLocked方法,这个方法也很长,我们只关注重点的方法,不然就会陷入只见树木,不见森林的尴尬境地。

  final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
            ...
              // switch back to it faster and look better.
        if (isFrontStack(stack)) {
            mService.startSetupActivityLocked();
        }
            ...
            }

接着掉了ActivityManagerService#startSetupActivityLocked

 void startSetupActivityLocked() {
     ...
      mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
                            null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
                            null, null, null);
     ...
 }

接着又回调到了ActivityStackSupervisor#startActivityLocked方法,haha这个方法也很长,不过别慌,我们还是老规矩,只贴重点方法

 final int startActivityLocked(IApplicationThread caller,
            Intent intent, String resolvedType, ActivityInfo aInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode,
            int callingPid, int callingUid, String callingPackage,
            int realCallingPid, int realCallingUid, int startFlags, Bundle options,
            boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
            ActivityContainer container, TaskRecord inTask) {
                ...
                 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, true, options, inTask);
                ...
            }

然后是掉了ActivityStackSupervisor#startActivityUncheckedLocked,方法很长,我们也只看重点

 final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
            boolean doResume, Bundle options, TaskRecord inTask) {
                ...
                   targetStack.startActivityLocked(r, newTask, doResume, keepCurTranstion, options);
                ...
            }

然后掉了ActivityStack#startActivityLocked方法

 final void startActivityLocked(ActivityRecord r, boolean newTask,
            boolean doResume, boolean keepCurTransition, Bundle options) {
                ...
                
        if (doResume) {
            mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
        }
                ...
            }

然后ActivityStackSupervisor#resumeTopActivitiesLocked方法

 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
            Bundle targetOptions) {
            //这个地方要注意,调用的不是循环里面的resumeTopActivityLocked方法。
                ...
                   if (isFrontStack(targetStack)) {
            result = targetStack.resumeTopActivityLocked(target, targetOptions);
        }
                ...
            }

然后就是ActivityStack#resumeTopActivityLocked方法

final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
        if (mStackSupervisor.inResumeTopActivity) {
            // Don't even start recursing.
            return false;
        }

        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
                mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
                mService.updateSleepIfNeededLocked();
            }
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        return result;
    }
    
 final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
       ...
        result = resumeTopActivityInnerLocked(prev, options);
       ...
    }
//这个方法也很长,只贴重点方法
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
    ...
     mStackSupervisor.startSpecificActivityLocked(next, true, true);
    ...
}

接着回到ActivityStackSupervisor#startSpecificActivityLocked

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
                ...
                 realStartActivityLocked(r, app, andResume, checkConfig);
                ...
            }

走了这么多不,而realStartActivityLocked方法就是真正的去开启一个Activity的方法。

   final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
                ...
                 app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
                ...
            }

app.thread其实就是ApplicationThread,所以最后调用的其实就是ApplicationThread#scheduleLaunchActivity

  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) {
                    ...
                     sendMessage(H.LAUNCH_ACTIVITY, r);
                    ...
                }

最终发送handler消息给H

 public void handleMessage(Message msg) {
     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);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
       } 
       break;
 }
 
  private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { 
      ...
      Activity a = performLaunchActivity(r, customIntent);
      
        handleResumeActivity(r.token, false, r.isForward,
                    !r.activity.mFinished && !r.startsNotResumed);
      ...
  }
  //顺便再提一嘴,activity的布局绘制其实就在handleResumeActivity方法俩面的这一行代码开始的
   wm.addView(decor, l);

接着看handleLaunchActivity方法

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
     ...
     Activity activity = null;
        try {
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            //这里就是创建activity的实例,可以看出是通过反射创建的
            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 {
        //这部分是创建应用的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) {
                Context appContext = createBaseContextForActivity(r, activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config = new Configuration(mCompatConfiguration);
                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
                        + r.activityInfo.name + " with config " + config);
                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);

                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;
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                   //这里就是通过Instrumentation去调用activity的onCreate方法的地方, 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;
                if (!r.activity.mFinished) {
                    activity.performStart();
                    r.stopped = false;
                }
                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);
                    }
                }
                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;

            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;
     ...
 }
 
  public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
            //如果application存在直接返回,这里可以确定一个app只有一个application了
        if (mApplication != null) {
            return mApplication;
        }
        ...
        }
        
  public void callActivityOnCreate(Activity activity, Bundle icicle) {
        prePerformCreate(activity);
        //Here we go,真正的去执行activity的onCreate的地方
        activity.performCreate(icicle);
        postPerformCreate(activity);
    }
    
    final void performCreate(Bundle icicle, PersistableBundle persistentState) {
        restoreHasCurrentPermissionRequest(icicle);
        /真正的onCreate的方法执行的地方。
        onCreate(icicle, persistentState);
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
    }

上面这部分的代码估计能解决你对activity的大部分疑问,
里买呢又创建activity的过程,onCreate方法的调用等,具体逻辑在上面的代码中已经写处理啊了。

到这里Acvitiy的启动流程我们就介绍完了,下面我会把Activity的启动流程图贴出来,相对干巴巴的代码,我们可能会觉得流程图更清晰一些,就像会说话的人,眼睛看到那里他好像就能告诉我们在流程的什么地方了;如果我们在看代码逻辑的时候觉得思绪很乱,往往流程图能更清晰的从全局去理解和掌握代码的执行流程。

  • 流程图

    • 流程图地址,流程图是用在线的ProcessOn软件做的,如果分析的那些地方有错误不正确还请指出,谢谢。

流程图

展开阅读全文

没有更多推荐了,返回首页