Android7.0startActivity启动过程分析

文章在http://gityuan.com/2016/03/12/start-activity/基础上修改而来

. 简述

本文基于android7.0代码,分析Activity的启动流程

startActivity的流程与startService启动过程分析相近,但比多了stack/task以及UI的相关内容以及Activity的生命周期的管理。

Activity启动发起后,通过Binder最终交由system进程中的AMS来完成,则启动流程如下图(6.0的流程图)

下面就开始我们的分析

.启动流程

2.1 Activity.startActivity

[-> Activity.java]

    public void startActivity(Intent intent) {

        this.startActivity(intent, null);

    }

    public void startActivity(Intent intent,@Nullable Bundle options) {

        if (options != null) {

            startActivityForResult(intent, -1,options);

        } else {

            // Note we want to go through thiscall for compatibility with

            // applications that may haveoverridden the method.

            startActivityForResult(intent, -1);

        }

    }

2.2 startActivityForResult

[-> Activity.java]

    public voidstartActivityForResult(@RequiresPermission Intent intent, int requestCode) {

        startActivityForResult(intent,requestCode, null);

    }

 

    public voidstartActivityForResult(@RequiresPermission Intent intent, int requestCode,

            @Nullable Bundle options) {

        if (mParent == null) {

            Instrumentation.ActivityResult ar =

                mInstrumentation.execStartActivity(

                    this,mMainThread.getApplicationThread(), mToken, this,

                    intent, requestCode,options);

           ...

    }

       execStartActivity()方法的参数:

  • mAppThread: 数据类型为ApplicationThread,通过mMainThread.getApplicationThread()方法获取。这里获取的到对象在创建进程的时候创建而来。
  • mToken: 数据类型为IBinder.

2.3 execStartActivity

[-> Instrumentation.java]

    public ActivityResult execStartActivity(

            Context who, IBinder contextThread,IBinder token, Activity target,

            Intent intent, int requestCode,Bundle options) {

        android.util.SeempLog.record_str(377,intent.toString());

        IApplicationThread whoThread =(IApplicationThread) contextThread;

        Uri referrer = target != null ?target.onProvideReferrer() : null;

        if (referrer != null) {

           intent.putExtra(Intent.EXTRA_REFERRER, referrer);

        }

        ...

        try {

           intent.migrateExtraStreamToClipData();

            intent.prepareToLeaveProcess(who);

            int result =ActivityManagerNative.getDefault()

                .startActivity(whoThread,who.getBasePackageName(), intent,

                       intent.resolveTypeIfNeeded(who.getContentResolver()),

                        token, target != null ?target.mEmbeddedID : null,

                        requestCode, 0, null,options);

            //检查activity是否启动成功

            checkStartActivityResult(result,intent);

        } catch (RemoteException e) {

            throw newRuntimeException("Failure from system", e);

        }

        return null;

    }

 ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象. 此处startActivity()的共有10个参数, 下面说说每个参数传递AMP.startActivity()每一项的对应值:

  • caller: 当前应用的ApplicationThread对象mAppThread;
  • callingPackage: 调用当前ContextImpl.getBasePackageName(),获取当前Activity所在包名;
  • intent: 这便是启动Activity时,传递过来的参数;
  • resolvedType: 调用intent.resolveTypeIfNeeded而获取;
  • resultTo: 来自于当前Activity.mToken
  • resultWho: 来自于当前Activity.mEmbeddedID
  • requestCode = -1;
  • startFlags = 0;
  • profilerInfo = null;
  • options = null;

2.4 AMP.startActivity

[-> ActivityManagerNative.java :: ActivityManagerProxy]

classActivityManagerProxy implements IActivityManager

{

    public int startActivity(IApplicationThreadcaller, String callingPackage, Intent intent,

            String resolvedType, IBinderresultTo, String resultWho, int requestCode,

            int startFlags, ProfilerInfoprofilerInfo, Bundle options) throws RemoteException {

        Parcel data = Parcel.obtain();

        Parcel reply = Parcel.obtain();

       data.writeInterfaceToken(IActivityManager.descriptor);

        data.writeStrongBinder(caller != null ?caller.asBinder() : null);

        data.writeString(callingPackage);

        intent.writeToParcel(data, 0);

        data.writeString(resolvedType);

        data.writeStrongBinder(resultTo);

        data.writeString(resultWho);

        data.writeInt(requestCode);

        data.writeInt(startFlags);

        if (profilerInfo != null) {

            data.writeInt(1);

            profilerInfo.writeToParcel(data,Parcelable.PARCELABLE_WRITE_RETURN_VALUE);

        } else {

            data.writeInt(0);

        }

        if (options != null) {

            data.writeInt(1);

            options.writeToParcel(data, 0);

        } else {

            data.writeInt(0);

        }

       mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);

        reply.readException();

        int result = reply.readInt();

        reply.recycle();

        data.recycle();

        return result;

    }

...

}

AMP经过binder IPC,进入ActivityManagerNative(AMN)。接下来程序进入了system_server进程,开始继续执行。先前的操作都是在启动Activity的进程里执行。

2.5 AMN.onTransact

[-> ActivityManagerNative.java]

    @Override

    public boolean onTransact(int code, Parceldata, Parcel reply, int flags)

            throws RemoteException {

        switch (code) {

        case START_ACTIVITY_TRANSACTION:

        {

           data.enforceInterface(IActivityManager.descriptor);

            IBinder b =data.readStrongBinder();

            IApplicationThread app = ApplicationThreadNative.asInterface(b);

            String callingPackage =data.readString();

            Intent intent =Intent.CREATOR.createFromParcel(data);

            String resolvedType =data.readString();

            IBinder resultTo = data.readStrongBinder();

            String resultWho =data.readString();

            int requestCode = data.readInt();

            int startFlags = data.readInt();

            ProfilerInfo profilerInfo =data.readInt() != 0

                    ? ProfilerInfo.CREATOR.createFromParcel(data): null;

            Bundle options = data.readInt() !=0

                    ?Bundle.CREATOR.createFromParcel(data) : null;

            int result = startActivity(app,callingPackage, intent, resolvedType,

                    resultTo, resultWho, requestCode,startFlags, profilerInfo, options);

            reply.writeNoException();

            reply.writeInt(result);

            return true;

        }

此时startActivity执行的是AMSstartActivity方法

2.6 AMS.startActivity

[-> ActivityManagerService.java]

    @Override

    public final intstartActivity(IApplicationThread caller, String callingPackage,

            Intent intent, String resolvedType,IBinder resultTo, String resultWho, int requestCode,

            int startFlags, ProfilerInfoprofilerInfo, Bundle bOptions) {

        return startActivityAsUser(caller,callingPackage, intent, resolvedType, resultTo,

                resultWho, requestCode,startFlags, profilerInfo, bOptions,

                UserHandle.getCallingUserId());

    }

 

    @Override

    public final intstartActivityAsUser(IApplicationThread caller, String callingPackage,

            Intent intent, String resolvedType,IBinder resultTo, String resultWho, int requestCode,

            int startFlags, ProfilerInfoprofilerInfo, Bundle bOptions, int userId) {

       enforceNotIsolatedCaller("startActivity");

        userId =mUserController.handleIncomingUser(Binder.getCallingPid(),Binder.getCallingUid(),

                userId, false, ALLOW_FULL_ONLY,"startActivity", null);

        // TODO: Switch to user app stackshere.

        return mActivityStarter.startActivityMayWait(caller, -1,callingPackage, intent,

                resolvedType, null, null,resultTo, resultWho, requestCode, startFlags,

                profilerInfo, null, null,bOptions, false, userId, null, null);

    }

此处mActivityStarter类型为ActivityStarter,此类为7.0新加类,用于Activity的启动管理

2.7 AS.startActivityMayWait

当程序运行到这里时, AS.startActivityMayWait的各个参数取值如下:

  • caller = ApplicationThreadProxy, 用于跟调用者进程ApplicationThread进行通信的binder代理类.
  • callingUid = -1;
  • callingPackage = ContextImpl.getBasePackageName(),获取调用者Activity所在包名
  • intent: 这是启动Activity时传递过来的参数;
  • resolvedType = intent.resolveTypeIfNeeded
  • voiceSession = null;
  • voiceInteractor = null;
  • resultTo = Activity.mToken, 其中Activity是指调用者所在Activity, mToken对象保存自己所处的ActivityRecord信息
  • resultWho = Activity.mEmbeddedID, 其中Activity是指调用者所在Activity
  • requestCode = -1;
  • startFlags = 0;
  • profilerInfo = null;
  • outResult = null;
  • config = null;
  • options = null;
  • ignoreTargetSecurity = false;
  • userId = AMS.handleIncomingUser, 当调用者userId跟当前处于同一个userId,则直接返回该userId;当不相等时则根据调用者userId来决定是否需要将callingUserId转换为mCurrentUserId.
  • iContainer = null;
  • inTask = null;

再来看看这个方法的源码:

[-> ActivityStarter.java]

final intstartActivityMayWait(IApplicationThread caller, int callingUid,

            String callingPackage, Intentintent, String resolvedType,

            IVoiceInteractionSessionvoiceSession, IVoiceInteractor voiceInteractor,

            IBinder resultTo, String resultWho,int requestCode, int startFlags,

            ProfilerInfo profilerInfo,IActivityManager.WaitResult outResult, Configuration config,

            Bundle bOptions, booleanignoreTargetSecurity, int userId,

            IActivityContainer iContainer,TaskRecord inTask) {

        // Refuse possible leaked filedescriptors

        if (intent != null &&intent.hasFileDescriptors()) {

            throw newIllegalArgumentException("File descriptors passed in Intent");

        }

        mSupervisor.mActivityMetricsLogger.notifyActivityLaunching();

        boolean componentSpecified =intent.getComponent() != null;

 

        // Save a copy in case ephemeral needsit

        final Intent ephemeralIntent = newIntent(intent);

        // Don't modify the client's object!

        intent = new Intent(intent);

 

//收集Intent所指向的Activity信息, 当存在多个可供选择的Activity,则直接向用户弹出resolveActivity

        ResolveInfo rInfo = mSupervisor.resolveIntent(intent,resolvedType, userId);

        ...

        // Collect information about the targetof the Intent.

        ActivityInfo aInfo =mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo);

 

        ActivityOptions options =ActivityOptions.fromBundle(bOptions);

        ActivityStackSupervisor.ActivityContainercontainer =

               (ActivityStackSupervisor.ActivityContainer)iContainer;

        synchronized (mService) {

            if (container != null &&container.mParentActivity != null &&

                    container.mParentActivity.state!= RESUMED) {

                // Cannot start a childactivity if the parent is not resumed.

                returnActivityManager.START_CANCELED;

            }

            final int realCallingPid =Binder.getCallingPid();

            final int realCallingUid =Binder.getCallingUid();

            int callingPid;

            if (callingUid >= 0) {

                callingPid = -1;

            } else if (caller == null) {

                callingPid = realCallingPid;

                callingUid = realCallingUid;

            } else {

                callingPid = callingUid = -1;

            }

 

            final ActivityStack stack;

            if (container == null ||container.mStack.isOnHomeDisplay()) {

                stack = mSupervisor.mFocusedStack;

            } else {

                stack = container.mStack;

            }

            stack.mConfigWillChange = config !=null && mService.mConfiguration.diff(config) != 0;

            if (DEBUG_CONFIGURATION)Slog.v(TAG_CONFIGURATION,

                    "Starting activitywhen config will change = " + stack.mConfigWillChange);

 

            final long origId =Binder.clearCallingIdentity();

 

            if (aInfo != null &&

                   (aInfo.applicationInfo.privateFlags

                            &ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {

                // This may be a heavy-weightprocess!  Check to see if we already

                // have another, differentheavy-weight process running.

                if(aInfo.processName.equals(aInfo.applicationInfo.packageName)) {

                    final ProcessRecord heavy =mService.mHeavyWeightProcess;

                    if (heavy != null&& (heavy.info.uid != aInfo.applicationInfo.uid

                            ||!heavy.processName.equals(aInfo.processName))) {

                        int appCallingUid =callingUid;

                        if (caller != null) {

                            ProcessRecordcallerApp = mService.getRecordForAppLocked(caller);

                            if (callerApp != null) {

                                appCallingUid =callerApp.info.uid;

                            } else {

                                Slog.w(TAG,"Unable to find app for caller " + caller

                                        +" (pid=" + callingPid + ") when starting: "

                                        +intent.toString());

                               ActivityOptions.abort(options);

                                return ActivityManager.START_PERMISSION_DENIED;

                            }

                        }

 

                        IIntentSender target =mService.getIntentSenderLocked(

                               ActivityManager.INTENT_SENDER_ACTIVITY, "android",

                                appCallingUid,userId, null, null, 0, new Intent[] { intent },

                                new String[] {resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT

                                        |PendingIntent.FLAG_ONE_SHOT, null);

 

                        Intent newIntent = newIntent();

                        if (requestCode >=0) {

                            // Caller isrequesting a result.

                           newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_HAS_RESULT, true);

                        }

                       newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_INTENT,

                                newIntentSender(target));

                        if(heavy.activities.size() > 0) {

                            ActivityRecord hist =heavy.activities.get(0);

                           newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_APP,

                                   hist.packageName);

                            newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_CUR_TASK,

                                   hist.task.taskId);

                        }

                       newIntent.putExtra(HeavyWeightSwitcherActivity.KEY_NEW_APP,

                                aInfo.packageName);

                       newIntent.setFlags(intent.getFlags());

                       newIntent.setClassName("android",

                               HeavyWeightSwitcherActivity.class.getName());

                        intent = newIntent;

                        resolvedType = null;

                        caller = null;

                        callingUid =Binder.getCallingUid();

                        callingPid =Binder.getCallingPid();

                        componentSpecified =true;

                        rInfo =mSupervisor.resolveIntent(intent, null /*resolvedType*/, userId);

                        aInfo = rInfo != null ?rInfo.activityInfo : null;

                        if (aInfo != null) {

                            aInfo =mService.getActivityInfoForUser(aInfo, userId);

                        }

                    }

                }

            }

 

            final ActivityRecord[] outRecord =new ActivityRecord[1];

//[见流程2.8]

            int res = startActivityLocked(caller, intent,ephemeralIntent, resolvedType,

                    aInfo, rInfo, voiceSession,voiceInteractor,

                    resultTo, resultWho,requestCode, callingPid,

                    callingUid, callingPackage,realCallingPid, realCallingUid, startFlags,

                    options,ignoreTargetSecurity, componentSpecified, outRecord, container,

                    inTask);

 

            ...

            return res;

        }

该过程主要功能:通过resolveActivity来获取ActivityInfo信息, 找到相应的Activity组件,并保存到intent对象,然后再进入startActivityLocked()

2.7.1 ASS.resolveActivity

ASS代表ActivityStackSupervisor

[-> ActivityStackSupervisor.java]

       ActivityInfo resolveActivity(Intentintent, String resolvedType, int startFlags,

            ProfilerInfo profilerInfo, intuserId) {

        final ResolveInfo rInfo = resolveIntent(intent,resolvedType, userId);

        return resolveActivity(intent, rInfo, startFlags,profilerInfo);

    }

 

    ResolveInfo resolveIntent(Intent intent, StringresolvedType, int userId) {

        return resolveIntent(intent,resolvedType, userId, 0);

    }

 

    ResolveInfo resolveIntent(Intent intent, StringresolvedType, int userId, int flags) {

        try {

            returnAppGlobals.getPackageManager().resolveIntent(intent, resolvedType,

                   PackageManager.MATCH_DEFAULT_ONLY | flags

                    |ActivityManagerService.STOCK_PM_FLAGS, userId);

        } catch (RemoteException e) {

        }

        return null;

    }

    ActivityInfo resolveActivity(Intent intent, ResolveInfo rInfo,int startFlags,

            ProfilerInfo profilerInfo) {

        final ActivityInfo aInfo = rInfo !=null ? rInfo.activityInfo : null;

        if (aInfo != null) {

            // Store the found target back intothe intent, because now that

            // we have it we never want to dothis again.  For example, if the

            // user navigates back to thispoint in the history, we should

            // always restart the exact sameactivity.

            intent.setComponent(newComponentName(

                   aInfo.applicationInfo.packageName, aInfo.name));

 

            // Don't debug things in the systemprocess

            if (!aInfo.processName.equals("system")){

                ... //对于非system进程,根据flags来设置相应的debug信息

                     //推测是在启动进程里面设置

        return aInfo;

    }

ActivityManager类有如下4flags用于调试:

  • START_FLAG_ONLY_IF_NEEDED:
  • START_FLAG_DEBUG:用于调试debug app
  • START_FLAG_NATIVE_DEBUGGING:用于调试native
  • START_FLAG_TRACK_ALLOCATION: 用于调试allocation tracking

2.8 AS.startActivityLocked

[->ActivityStarter.java]

AS.StartActivityLocked代码较长,所以就不贴上具体代码了但是主要的工作为:

·        获取调用者的进程信息和调用Activity

·        为启动Activity做一些检查工作,比如检查ComponentActivityInfo…以及权限检查

·        创建ActivityRecord

·        获取当前的stack,执行checkAppSwitchAllowedLocked [见流程2.8.1]

·        处理pendind Activity的启动,这些Activity是由于appswitch禁用从而被hold的等待启动activity [见流程2.8.2]

  • startActivityUnchecked [见流程2.9

2.8.1AMS.checkAppSwitchAllowedLocked

[->ActivityStarter.java]

    boolean checkAppSwitchAllowedLocked(intsourcePid, int sourceUid,

            int callingPid, int callingUid,String name) {

        if (mAppSwitchesAllowedTime <SystemClock.uptimeMillis()) {

            return true;

        }

 

       int perm = checkComponentPermission(

               android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,

                sourceUid, -1, true);

        if (perm ==PackageManager.PERMISSION_GRANTED) {

            return true;

        }

 

        // If the actual IPC caller isdifferent from the logical source, then

        // also see if they are allowed tocontrol app switches.

        if (callingUid != -1 &&callingUid != sourceUid) {

            perm = checkComponentPermission(

                    android.Manifest.permission.STOP_APP_SWITCHES,callingPid,

                    callingUid, -1, true);

            if (perm ==PackageManager.PERMISSION_GRANTED) {

                return true;

            }

        }

 

        Slog.w(TAG, name + " request from" + sourceUid + " stopped");

        return false;

    }

mAppSwitchesAllowedTime时间小于当前时长,或者具有STOP_APP_SWITCHES的权限,则允许app发生切换操作.

其中mAppSwitchesAllowedTime,AMS.stopAppSwitches()的过程中会设置为:mAppSwitchesAllowedTime =SystemClock.uptimeMillis() + APP_SWITCH_DELAY_TIME. 禁止app切换的timeout时长为5s(APP_SWITCH_DELAY_TIME = 5s).

当发送5秒超时或者执行AMS.resumeAppSwitches()过程会将mAppSwitchesAllowedTime设置0, 都会开启允许app执行切换的操作.另外,禁止App切换的操作,对于同一个app是不受影响的,有兴趣可以进一步查看checkComponentPermission过程.

2.8.2 AS.doPendingActivityLaunchesLocked

[->ActivityStarter.java]

    final voiddoPendingActivityLaunchesLocked(boolean doResume) {

        while(!mPendingActivityLaunches.isEmpty()) {

            final PendingActivityLaunch pal =mPendingActivityLaunches.remove(0);

            final boolean resume = doResume&& mPendingActivityLaunches.isEmpty();

            try {

                final int result =startActivityUnchecked(

                        pal.r, pal.sourceRecord,null, null, pal.startFlags, resume, null, null);

               postStartActivityUncheckedProcessing(

                        pal.r, result,mSupervisor.mFocusedStack.mStackId, mSourceRecord,

                        mTargetStack);

            } catch (Exception e) {

                Slog.e(TAG, "Exceptionduring pending activity launch pal=" + pal, e);

                pal.sendErrorResult(e.getMessage());

            }

        }

    }

mPendingActivityLaunches记录着所有将要启动的Activity, 是由于在startActivityLocked的过程时App切换功能被禁止, 也就是不运行切换Activity, 那么此时便会把相应的Activity加入到mPendingActivityLaunches队列. 该队列的成员在执行完doPendingActivityLaunchesLocked便会清空.

启动mPendingActivityLaunches中所有的Activity, 由于doResume =false, 那么这些activtity并不会进入resume状态,而是设置delayedResume = true, 会延迟resume.

2.9 AS. startActivityUnchecked

[->ActivityStarter.java]

同样ActivityStarterstartActivityUnchecked代码也非常多,主要工作如下:

  • 调用setInitialState对Activity的Flags做处理
  • computeLaunchingTaskFlags判断是否需要创建新的Task
  • 寻找getReusableIntentActivity是否有可重复使用的Activity
  • 该方法中主要包括对Task是否创建的逻辑处理以及Activity的管理

ActivityInfo.java中定义了4Launch Mode

  • LAUNCH_MULTIPLE(standard):最常见的情形,每次启动Activity都是创建新的Activity;
  • LAUNCH_SINGLE_TOP: 当Task顶部存在同一个Activity则不再重新创建;其余情况同上;
  • LAUNCH_SINGLE_TASK:当Task栈存在同一个Activity(不在task顶部),则不重新创建,而移除该Activity上面其他的Activity;其余情况同上;
  • LAUNCH_SINGLE_INSTANCE:每个Task只有一个Activity.

还有几个常见的flag含义:

  • FLAG_ACTIVITY_NEW_TASK:将Activity放入一个新启动的Task;
  • FLAG_ACTIVITY_CLEAR_TASK:启动Activity时,将目标Activity关联的Task清除,再启动新Task,将该Activity放入该Task。该flags跟FLAG_ACTIVITY_NEW_TASK配合使用。
  • FLAG_ACTIVITY_CLEAR_TOP:启动非栈顶Activity时,先清除该Activity之上的Activity。例如Task已有A、B、C3个Activity,启动A,则清除B,C。类似于SingleTop。

最后还有:设置FLAG_ACTIVITY_NEW_TASK的几个情况:

  • 调用者并不是Activity context;
  • 调用者activity带有single instance;
  • 目标activity带有single instance或者single task;
  • 调用者处于finishing状态;

2.9.1 AStack.startActivityLocked

[->ActivityStack.java]

2.10ASS. resumeFocusedStackTopActivityLocked

[->ActivityStackSupervisor.java]

 

2.11AStack. resumeTopActivityUncheckedLocked

[->ActivityStack.java]

2.12AStack. resumeTopActivityInnerLocked

[->ActivityStack.java]

2.13ASS.startSpecificActivityLocked

[->ActivityStackSupervisor.java]

    voidstartSpecificActivityLocked(ActivityRecord r,

            boolean andResume, booleancheckConfig) {

        // Is this activity's applicationalready running?

        ProcessRecord app =mService.getProcessRecordLocked(r.processName,

                r.info.applicationInfo.uid,true);

 

        r.task.stack.setLaunchTime(r);

 

        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 isa platform component that is marked

                    // to run in multiple processes,because this is actually

                    // part of the framework sodoesn't make sense to track as a

                    // separate apk in theprocess.

                   app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,

                           mService.mProcessStats);

                }

//真正的启动Activity【见流程2.14

                realStartActivityLocked(r, app,andResume, checkConfig);

                return;

            } catch (RemoteException e) {

                Slog.w(TAG, "Exceptionwhen starting activity "

                        +r.intent.getComponent().flattenToShortString(), e);

            }

 

            // If a dead object exception wasthrown -- fall through to

            // restart the application.

        }

//当进程不存在则创建进程 [见流程2.13.1]

       mService.startProcessLocked(r.processName, r.info.applicationInfo, true,0,

                "activity",r.intent.getComponent(), false, false, true);

    }

2.13.1AMS.startProcessLocked

[->ActivityManagerService.java]

AMS.startProcessLocked()就是系统开始创建进程的入口,关于系统创建进程的流程也是值得深究的。

Zygote进程收到创建进程的消息之后,通过fork方法,创建出一个新的进程,创建结束后会在这个新的进程里创建属于它的ActivityThread,然后执行了ActivityThreadattach方法,通过这个方法建立与系统进程的联系,这里暂且不讨论过多与创建进程相关的东西,当做完以上操作时便会执行到2.14

2.14 ASS.realStartActivityLocked

[->ActivityStackSupervisor.java]

我们回溯到ASS.realStartActivityLocked[流程2.13],如果在启动Activity或者其他android的组件时,有承载它的进程,则直接执行该方法继续Activity的创建流程,如果没有则为其创建相应的进程,然后还会继续执行本方法

 

2.15ATP.scheduleLaunchActivity

[->ApplicationThreadProxy.java]

    public final voidscheduleLaunchActivity(Intent intent, IBinder token, int ident,

            ActivityInfo info, ConfigurationcurConfig, Configuration overrideConfig,

            CompatibilityInfo compatInfo,String referrer, IVoiceInteractor voiceInteractor,

            int procState, Bundle state,PersistableBundle persistentState,

            List<ResultInfo>pendingResults, List<ReferrerIntent> pendingNewIntents,

            boolean notResumed, booleanisForward, ProfilerInfo profilerInfo) throws RemoteException {

......

mRemote.transact(SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION,data, null,

                IBinder.FLAG_ONEWAY);

.......

}

2.16 ATN.onTransact

[-> ApplicationThreadNative.java]

    case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:

        {

            ......

            scheduleLaunchActivity(intent, b,ident, info, curConfig, overrideConfig, compatInfo,

                    referrer, voiceInteractor, procState,state, persistentState, ri, pi,

                    notResumed, isForward,profilerInfo);

            return true;

        }

2.17AT.scheduleLaunchActivity

[-> ApplicationThread.java]

这里的代码比较容易理解,主要通过AndroidHandler消息机制发送一个消息给承载将要启动此Activity的进程,告诉它我们要开始启动Activity

2.18 H.handleMessage

[-> ActivityThread.java ::H]

执行handleLaunchActivity,详细见[流程2.19]

2.19 AT.handleLaunchActivity

[-> ActivityThread.java]

    private voidhandleLaunchActivity(ActivityClientRecord r, Intent customIntent, Stringreason) {

      ........

 

       //初始化wms

        WindowManagerGlobal.initialize();

//最终回调目标ActivityonCreate[见流程2.23]

        Activity a = performLaunchActivity(r, customIntent);

 

        if (a != null) {

            r.createdConfig = newConfiguration(mConfiguration);

            reportSizeConfigurations(r);

            Bundle oldState = r.state;

//最终回调目标ActivityonStart,onResume.

            handleResumeActivity(r.token,false, r.isForward,

                    !r.activity.mFinished&& !r.startsNotResumed, r.lastProcessedSeq, reason);

 

  .......

    }

  • 初始化WMS为后面的Activity.attach做准备
  • 执行performLaunchActivity,回调Activity的onCreate方法
  • 执行handleResumeActivity,继续Activity的生命周期的方法

2.20 AT.performLaunchActivity

[-> ActivityThread.java]

private ActivityperformLaunchActivity(ActivityClientRecord r, Intent customIntent) {

        .......

        Activity activity = null;

        ......

 

        try {

            Application app = r.packageInfo.makeApplication(false,mInstrumentation);

 

            ......

                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);

 

              ......

 

        return activity;

    }

创建Activity对象

创建Application对象

调用Activityattach方法Activity的一些成员变量进行了初始化(上下文,线程,标题。。。),特别是mWindow初始化为PhoneWindow这个类的实例。在初始化了Window之后,来到我们最熟悉的onCreate方法,我们一般在这个方法中会调用setContentView指定该Activity的布局文件[这里涉及Activity界面的加载和绘制],然后继续[流程2.21]

2.21 AT. handleResumeActivity

[-> ActivityThread.java]

AT. handleResumeActivity主要回调Activityonstartonresume方法,主要处理和Activity的显示相关的操作,详细参见[Activity界面的加载和绘制]

.总结

到这里就已经简单的介绍了startActivity的整个启动流程,其中的一些过程或许也有疏漏,还请见谅。

  • 流程[2.1 ~2.4]:运行在调用者所在进程,比如从桌面启动Activity,则调用者所在进程为launcher进程,launcher进程利用ActivityManagerProxy作为Binder Client,进入system_server进程(AMS相应的Server端)。
  • 流程[2.5 ~2.15]:则运行在system_server进程
  • 流程[2.16 ~2.21]:则运行在承载即将启动的Activity的进程,通过Handler消息机制,该进程中的Binder线程向主线程发送H.LAUNCH_ACTIVITY,最终会通过反射原理创建目标Activity,然后进入onCreate()生命周期,接着走Activity的生命周期中的其他方法

然后我们要启动的Activity的就start起来了,从onCreateonStartonResumeActivity界面的绘制……

完毕

你可能感兴趣的:(android,Activity,startactivity)