Android根Activity的启动过程

本文内容多是出自《Android进阶解密》一书。所以,可能不会为大家提供多少帮助,我写本文的目的只是为了自己再学习的时候能够有个印象,为自己提供一个方便。

现在开始记录根Activity的启动过程。该过程很复杂,讲述的是从手机开机进入桌面之后,点击屏幕上App的应用图标开始,直到App启动后显示的第一个应用程序Activity的过程。可以分为三个部分,分别是Launcher请求AMS的过程,AMS到ApplicationThread的调用过程和ActivityThread启动Activity的过程。

一、Launcher请求AMS的过程

1. 点击应用图标会调用Launcher3的startActivitySafely方法,该方法中有两个点需要注意

1)intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这句代码会让Activity在新的任务栈中启动

2)startActivitySafely方法中会调用到startActivity(intent.optsBundle);这个startActivity方法会在Activity中实现。

2. 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);
    }
}

该方法调用了startActivityForResult(intent,-1,options);方法。第二个参数-1表示Launcher不需要知道Activity的启动结果。下面看一下startActivityForResult方法的源码:

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options) {
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            Instrumentation.ActivityResult ar =
                mInstrumentation.execStartActivity(
                    this, mMainThread.getApplicationThread(), mToken, this,
                    intent, requestCode, options);   
            // 代码省略         
        } 

        // 代码省略

}

源码中调用了Instrumentation的execStartActivity方法,Instrumentation主要用来监护应用程序和系统的交互。execStartActivity方法代码比较多,但是我们只需要分析其中最重要的部分。代码如下:

public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        // 代码省略
        try {
            // .......
            // 主要代码
            int result = ActivityManager.getService()
                .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);
        }
        return null;
    }

ActivityManager.getService()方法调用了IActivityManagerSingleTon.get(),IActivityManagerSingleTon是一个Singleton类。它的onCreate方法代码如下:

@Override
protected IActivityManager create() {

    // 注释1
    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);

    // 注释2
    final IActivityManager am = IActivityManager.Stub.asInterface(b);
    return am;
}

注释1处,得到名为"activity"的Service类型的对象,其实也就是IBinder类型的AMS引用。注释2处,是将上一步得到的IBinder类型AMS引用转换成IActivityManager类型的对象,这段代码采用的是AIDL,IActivityManager.java类是由AIDL工具在编译时自动生成的。因此execStartActivity方法最终调用的是AMS的startActivity方法。

至此,Launcher到ActivityManagerService的过程就分析完了。附上一张时序图,从图中更能看出大致的流程:

二、AMS到ApplicationThread的调用过程

1. 在AMS中代码首先会调用到AMS的startActivity方法,该方法中返回了startActivityAsUser方法,这个方法比startActivity方法多了一个参数UserHandle.getCallingUserId(),这个方法会获得调用者的userId,AMS会根据这个UserId来确定调用者的权限。startActivityAsUser方法源码如下:

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

1)注释1处,判断调用者进程是否被隔离。被隔离则抛出SecurityException异常。

2)注释2处,检查调用者权限,没权限则会抛出SecurityException异常。

3)注释3处,调用了ActivityStarter.startActivityMayWait方法。其中startActivityMayWait方法倒数第二个参数类型为TaskRecord,代表启动的Activity所在的栈。最后一个参数"startActivityAsUser"代表启动的理由。

2. ActivityStarter的startActivityMayWait方法,该方法中返回了startActivityLocked方法。而startActivityLocked方法中对reason(启动理由)做了判断,如果为空抛出了IllegalArgumentException异常,紧接着调用了startActivity方法。下面看一下这个startActivity方法中做了什么。源码如下:

/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
    private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
            String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
            String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
            ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
            ActivityRecord[] outActivity, ActivityStackSupervisor.ActivityContainer container,
            TaskRecord inTask) {
        
        // 。。。。。。

        ProcessRecord callerApp = null;
        // 注释1
        if (caller != null) {
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
                callingPid = callerApp.pid;
                callingUid = callerApp.info.uid;
            } else {
                Slog.w(TAG, "Unable to find app for caller " + caller
                        + " (pid=" + callingPid + ") when starting: "
                        + intent.toString());
                err = ActivityManager.START_PERMISSION_DENIED;
            }
        }

        
        // 代码省略。。。
        
        // 注释2 创建ActivityRecord
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                mSupervisor, container, options, sourceRecord);
        if (outActivity != null) {
            outActivity[0] = r;
        }

       
        // 代码省略
        
        // 注释3
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                options, inTask, outActivity);
    }

代码很多,即便是省略掉一部分也不少。其中注释1处,caller是方法调用传下来的,指向的是Launcher所在的应用程序进程的ApplicationThread对象,callerApp是代表Launcher进程的对象,它是ProcessRecord类型的,ProcessRecord用于描述一个应用程序进程。同样地,ActivityRecord用于描述一个Activity,用来记录一个Activity的所有信息。接下来创建ActivityRecord,并将其对象r赋值给了outActivity[0],最终outActivity作为注释3处startActivity方法的参数使用。而这个startActivity方法中调用了startActivityUnChecked方法。startActivityUnChecked方法的代码如下:

// Note: This method should only be called from {@link startActivity}.
    private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
        
        // 代码省略。。。。
       

        // Should this be considered a new task?
        int result = START_SUCCESS;
        // 注释1
        if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            // 注释2。。。。
            result = setTaskFromReuseOrCreateNewTask(
                    taskToAffiliate, preferredLaunchStackId, topStack);
        } 

        if (mDoResume) {
            final ActivityRecord topTaskActivity =
                    mStartActivity.getTask().topRunningActivityLocked();
            if (!mTargetStack.isFocusable()
                    || (topTaskActivity != null && topTaskActivity.mTaskOverlay
                    && mStartActivity != topTaskActivity)) {
                
                mTargetStack.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
                
                mWindowManager.executeAppTransition();
            } else {
                
                if (mTargetStack.isFocusable() && !mSupervisor.isFocusedStack(mTargetStack)) {
                    mTargetStack.moveToFront("startActivityUnchecked");
                }
                // 注释3。。。
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        // 。。。。。
    }

startActivityUnchecked方法主要处理栈管理相关的逻辑。启动根Activity时在Launcher的startActivitySafely方法中将Intent的Flag设置为FLAG_ACTIVITY_NEW_TASK。因此可以执行到setTaskFromReuseOrCreateNewTask方法,这个方法的内部会创建一个新的Activity任务栈,接着代码会执行ActivityStackSupervisor的resumeFocusedStackTopActivityLocked方法,此方法中:

final ActivityRecord r = mFocusedStack.topRunningActivityLocked();

就是获取要启动的Activity所在栈的栈顶的不是处于停止状态的ActivityRecord。对于即将要启动的Activity条件判断

if(r == null || r.state != RESUMED)

成立,所以代码会执行:

mFocusedStack.resumeTopActivityUnCheckedLocked(null,null);

ActivityStack的resumeTopActivityUnCheckedLocked方法的代码如下:

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
        
        boolean result = false;
        try {
            // Protect against recursion.
            mStackSupervisor.inResumeTopActivity = true;
            // 注释1。。。
            result = resumeTopActivityInnerLocked(prev, options);
        } finally {
            mStackSupervisor.inResumeTopActivity = false;
        }
        
        return result;
    }

注释1处调用了resumeTopActivityInnerLocked方法,代码如下:

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        
            // 代码省略。。。。

            if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);

            // 关键代码

            mStackSupervisor.startSpecificActivityLocked(next, true, true);
        }

        if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
        return true;
    }

在此方法中,调用了ActivityStackSupervisor的startSpecificActivityLocked方法。代码如下:

void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
        // Is this activity's application already running?
        // 获取即将启动的Activity的所在应用程序进程
        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);
        // 判断要启动的Activity所在的应用程序进程是否已经运行
        if (app != null && app.thread != null) {
            try {
                
                // 真正的启动Activity,参数二代表要启动的Activity所在的应用程序进程的ProcessRecord
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }

            
        }

        // 代码省略。。。。
       
    }

在判断要启动的Activity所在的应用程序进程已经运行之后调用了realStartActivityLocked方法。该方法代码如下:

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,
                    // TODO: Have this take the merged configuration instead of separate global and
                    // override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
                    r.persistentState, results, newIntents, !andResume,
                    mService.isNextTransitionForward(), profilerInfo);

           // 代码省略。。。

        return true;
    }

此方法中代码很多,但是最重要的就是调用了app.thread.scheduleLaunchActivity方法。此处app.thread指的是IApplicationThread,它的实现是ActivityThread的内部类ApplicationThread,其中ApplicationThread继承了IApplicationThread.Stub。app指的是传入的要启动的Activity所在的应用程序进程。因此这段代码指的就是要在目标应用程序进程启动Activity。当前代码逻辑运行在AMS所在的进程(SystemServer)进程中,通过ApplicationThread来与应用程序进程进行Binder通信。因此,ApplicationThread是AMS所在进程(SystemServer进程)和应用程序进程的通信桥梁。至此,AMS到ApplicationThread的过程也就分析完了。这一过程的简易时序图如下:

三、ActivityThread启动Activity的过程

上一过程代码执行到了ApplicationThread的scheduleLaunchActivity方法,其中ApplicationThread是ActivityThread的内部类。scheduleLaunchActivity方法中将启动Activity的参数封装成ActivityClientRecord,最后调用了sendMessage(H.LAUNCH_ACTIVITY,r);方法向H类发送了一条类型为LAUNCH_ACTIVITY的消息,并将ActivityClientRecord传递过去。在H的handleMessage方法中对LAUNCH_ACTIVITY的处理如下:

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方法
                handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            } break;
                
    }

对LAUNCH_ACTIVITY的处理中,最重要的就是调用了handleLaunchActivity方法。其源码如下:

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        
        // 注释1

        Activity a = performLaunchActivity(r, customIntent);

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

            if (!r.activity.mFinished && r.startsNotResumed) {
                

                // 代码省略。。。。

        } else {
            // If there was an error, for any reason, tell the activity manager to stop us.
            try {
                
                // 注释3。。。
                ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

注释1处,调用performLaunchActivity方法启动Activity;注释2处,用来将Activity的状态置为Resume;注释3处,如果该Activity为null则会通知AMS停止启动Activity。performLaunchActivity方法的代码如下:

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

        // 注释1:获取ActivityInfo

        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) {
            // 注释2:获取APK文件的描述类LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        }

        // ComponentName类中保存了该Activity的包名和类名
        ComponentName component = r.intent.getComponent();
        
        // 代码省略。。。

        // 注释3:创建要启动的Activity的上下文环境

        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            // 注释4:用类加载器来创建该Activity的实例
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           
        } catch (Exception e) {
            //。。。
        }

        try {
            // 注释5:创建Application,makeApplication方法内部会调用Application的onCreate方法
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);

            // 。。。。            

            if (activity != null) {

                // 。。。。               
                //注释6:初始化Activity,attach方法中会创建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, r.configCallback);

                // 。。。。               

                if (r.isPersistable()) {
                    // 注释7:启动Activity
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                
                // .....
           

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            //....
        }

        return activity;
    }

在注释7处调用了Instrumentation类的callActivityOnCreate方法来启动Activity。代码如下:

/**
  * Perform calling of an activity's {@link Activity#onCreate}
  * method.  The default implementation simply calls through to that method.
  *  @param activity The activity being created.
  * @param icicle The previously frozen state (or null) to pass through to
  * @param persistentState The previously persisted state (or null)
  */
public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    // 调用了Activity的performCreate方法
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

该方法中调用了Activity的performCreate方法,代码如下:

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    restoreHasCurrentPermissionRequest(icicle);
    // 调用到了Activity的声明周期方法
    onCreate(icicle, persistentState);
    mActivityTransitionState.readState(icicle);
    performCreateCommon();
}

在Activity的performCreate方法中,调用到了具体Activity的onCreate的声明周期方法。至此根Activity的启动过程就分析完了,此时应用程序就启动了。这一过程的时序图如下:

好了,这篇文章到此就结束了,文章的开头也说了,内容基本是从《Android进阶解密》一书中看到的,仅是为了自己再次学习的时候方便些。在此对此书的作者表示感谢。

猜你喜欢

转载自blog.csdn.net/zhourui_1021/article/details/105590528