四大组件的工作过程之Activity的启动过程

Activity的启动过程

Android组件有四个,Activity、Service、ContentProvider、BroadcastReceiver。首先来学习activity的启动过程,Activity有两种类型,一个是根Activity,即应用程序的第一个Activity,一个是普通的Activity,启动根Activity即是启动该应用程序。首先来看一下如何去启动根Activity,从之前的学习知道,系统第一个应用程序是Laucnher,用于显示各种应用程序图标,之后再通过点击应用程序图标的方式去启动第三方应用程序,所以可知,应用程序的启动入口应该就在Launcher,事实上,应用程序的启动过程大概分为以下三步:

  1. Launcher请求AMS启动指定应用程序过程
  2. AMS调用ApplicationThread的过程
  3. ActivityThread启动指定根Activity

步骤一: Launcher请求AMS启动指定应用程序过程

首先来看一下大致的时序图:
在这里插入图片描述

1.点击应用程序图标,会调用Launcher的startActivitySafely方法:

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
			...
       // 1. 设置intent的flag为FLAG_ACTIVITY_NEW_TASK,那么该Activity会在一个新的栈中启动。
       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
       if (v != null) {
           intent.setSourceBounds(getViewBounds(v));
        }
       try {
            if (Utilities.ATLEAST_MARSHMALLOW
                    && (item instanceof ShortcutInfo)
                   && (item.itemType == Favorites.ITEM_TYPE_SHORTCUT
                    || item.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT)
                   && !((ShortcutInfo) item).isPromise()) {
               // Shortcuts need some special checks due to legacy reasons.
              startShortcutIntentSafely(intent, optsBundle, item);
           } else if (user == null || user.equals(Process.myUserHandle())) {
                //2. 调用startActivity去启动activity,这个startActivity在Activity中实现,那么去Activity中看一下这个实现:
                startActivity(intent, optsBundle);
           } else {
                LauncherAppsCompat.getInstance(this).startActivityForProfile(
                        intent.getComponent(), user, intent.getSourceBounds(), optsBundle);
           }
            return true;
       } catch (ActivityNotFoundException|SecurityException e) {
           Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
            Log.e(TAG, "Unable to launch. tag=" + item + " intent=" + intent, e);
       }
       return false;
   }

2.Activity.startActivityForResult()

startActivity()内部调用了startActivityForResult():

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,@Nullable Bundle options) {
		 //1. mParent表示要创建的Activity的父类,由于根Activity还没有创建出来,所以这里符合mParent == null
        if (mParent == null) {
            options = transferSpringboardActivityOptions(options);
            //2.接下来调用了 Instrumentation的execStartActivity()方法,Instrumentation主要用来监控应用程序和系统的交互,那么再来看下Instrumentation的execStartActivity()方法:
            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());
            }
            if (requestCode >= 0) {
                mStartedActivity = true;
            }

            cancelInputsAndStartExitTransition(options);
            // TODO Consider clearing/flushing other event sources and events for child windows.
        } else {
           ...
        }
    }

3. Instrumentation的execStartActivity()

public ActivityResult execStartActivity(Context who, IBinder contextThread, IBinder token, Activity target,Intent intent, int requestCode, Bundle options) {
		 ...
        try {
            intent.migrateExtraStreamToClipData();
            intent.prepareToLeaveProcess(who);
            //1. 这里主要工作就是获取AMS,然后调用AMS的tartActivity()方法,那么如何获取到AMS?
            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;
    }

4.通过ActivityManager.getService()获取AMS

public static IActivityManager getService() {
        return IActivityManagerSingleton.get(); //1. 调用IActivityManagerSingleton.get()
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                   
						//2.这里通过ServiceManager的getService()获取名为“activity”的service引用,即是IBinder类型的AMS引用,由于SystemServer启动时会创建各种service包括AMS,并都注册到
						// ServiceManager中,所以这里可以通过ServiceManager去获取各种Service。
						
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);  
                              
                    //3. 这里将这个引用转成IActivityManager 类型,这里采用了AIDL实现进程间通信,服务端即AMS继承IActivityManager.Stub类并实现相应的方法即可。 
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
            

public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(getIServiceManager().getService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
 }            
            

从上面步骤可知,从桌面点击应用程序图标会经历Launcher.startActivitySafely() -> Activity.startActivityForResult() -> Instrumentation的execStartActivity() -> AMS.startActivity(),即最终进入到AMS的StartActivity(),那么现在整个Activity的启动流程就进入了AMS,即已经跨入了另一进程了,那么再来看下第二个详细的步骤:

步骤二:AMS调用ApplicationThread的过程

1.首先来看AMS的startActivity()过程

AMS内部startActivity()会调用startActivityAsUser()方法,代码如下:

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. 判断调用者是否被隔离 ,如果被隔离则抛出SecurityException()   
        enforceNotIsolatedCaller("startActivity");
        //2. 检查调用者是否有权限
        userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
                userId, false, ALLOW_FULL_ONLY, "startActivity", null);
                
        //3. 最后一步调用ActivityStarter.startActivityMayWait()
        return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, null,
                "startActivityAsUser");
    }

2. ActivityStarter.startActivityMayWait()

ActivityStarter是加载Activity的控制类,收集所有的逻辑来判断该如何将Intent和flags转换成Activity,并将Activity和Task以及Stack相关联。

final int startActivityMayWait(IApplicationThread caller, int callingUid,...IActivityContainer iContainer, TaskRecord inTask, String reason) {
	...
   final ActivityRecord[] outRecord = new ActivityRecord[1];
   				//1. 内部调用了启动reason是否为空,为空则抛出异常,否则就跳转的StartActivity()
            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, reason);
             ...
             return res;
      }
}
                    

3.ActivityStarter.startActivity()

private int startActivity(IApplicationThread caller, Intent intent, ...TaskRecord inTask) {
		 int err = ActivityManager.START_SUCCESS;
   
        final Bundle verificationBundle = options != null ? options.popAppVerificationBundle() : null;

        ProcessRecord callerApp = null;
        //1 .判断caller是否为空,它是从开始一路传进来的,即调用者Launcher所在的应用程序进程的ApplicationThread对象
        if (caller != null) {
        		//2. 调用AMS去获取Launcher进程的callerApp对象,这是一个ProcessRecord,记录了进程所有相关的消息。
            callerApp = mService.getRecordForAppLocked(caller);
            if (callerApp != null) {
            		//获取Launcher进程的pid、uid
                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. 创建即将要启动的Activity的描述类ActivityRecord,ActivityRecord是用来记录一个Activity所有的信息。
        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. 
        }
        
        doPendingActivityLaunchesLocked(false);

		//3. 再次调用了startActivity(),内部调用了startActivityUnchecked()
        return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask, outActivity);
            

4.ActivityStarter.startActivityUnchecked()

startActivityUnchecked()主要处理与栈管理相关的逻辑:


private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask, ActivityRecord[] outActivity) {

	//1. 前面Launcher入口时就设置了Intent为	FLAG_ACTIVITY_NEW_TASK,所以这里的条件会满足
     if (mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
                && (mLaunchFlags & FLAG_ACTIVITY_NEW_TASK) != 0) {
            newTask = true;
            
            //2. 这里内部会创建一个新的TaskRecord,用于描述Activity的任务栈。
            result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);
            
        } else if (mSourceRecord != null) {
            result = setTaskFromSourceRecord();
        } else if (mInTask != null) {
            result = setTaskFromInTask();
        } else {
            setTaskToCurrentTopOrCreateNewTask();
        }
        
        ...
        
                   
        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. 最后这里会调用ActivityStackSupervisor的resumeFocusedStackTopActivityLocked()方法,那么这个方法又做了什么?
                mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity,
                        mOptions);
            }
        } else {
            mTargetStack.addRecentActivityLocked(mStartActivity);
        }
        mSupervisor.updateUserStackLocked(mStartActivity.userId, mTargetStack);

        mSupervisor.handleNonResizableTaskIfNeeded(mStartActivity.getTask(), preferredLaunchStackId,
                preferredLaunchDisplayId, mTargetStack.mStackId);

        return START_SUCCESS;

5. ActivityStackSupervisor.resumeFocusedStackTopActivityLocked()

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        if (targetStack != null && isFocusedStack(targetStack)) {
            return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
        }
        //1.获取当前要启动的Activity的栈顶处于running状态的Activity的ActivityRecord
        final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
        
        //2.若r == null 或者要启动的Activity不是resumed状态,则调用下面的mFocusedStack.resumeTopActivityUncheckedLocked,由于Activity还没启动。所以这里条件满足     
         if (r == null || r.state != RESUMED) {
        //3.这个resumeTopActivityUncheckedLocked()又做了什么?
            mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
        } else if (r.state == RESUMED) {
            // Kick off any lingering app transitions form the MoveTaskToFront operation.
            mFocusedStack.executeAppTransition(targetOptions);
        }
        return false;
    }

6. ActivityStack.resumeTopActivityUncheckedLocked()

resumeTopActivityUncheckedLocked()内部经过跳转,会调用startSpecificActivityLocked()方法:

void startSpecificActivityLocked(ActivityRecord r,boolean andResume, boolean checkConfig) {
        // 1. 获取即将要启动的ACtivity所在进程,判断该Activity所在进程是否已经running?
        ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);

        r.getStack().setLaunchTime(r);

        if (app != null && app.thread != null) {
            try {
                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0 || !"android".equals(r.info.packageName)) {
                    //给app添加包信息
                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,mService.mProcessStats);
                }
                //2. 判断app != null &&该应用程序进程已经运行时,执行下面方法,这个方法又做了什么?
                realStartActivityLocked(r, app, andResume, checkConfig);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when starting activity "
                        + r.intent.getComponent().flattenToShortString(), e);
            }
        }

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

7. realStartActivityLocked()

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
   ...
   /**
     * 这个方法的核心代码在这里, app.thread值得是IApplicationThread,它的实现类是ActivityThread的内部类ApplicationThread,继承自IApplicationThread.Stub
     * app就是待启动Activity的ProcessRecord,所以这里就是要在目标应用程序的进程里面启动Activity,上面的代码是运行在AMS进程中,现通过应用程序的ActivityThread的ApplicationThread就切换
     * 回到了应用程序进程,通过Binder进行通信。
     **/
    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;
 }                            

AMS和应用程序进程通信过程:

在这里插入图片描述

中间的这个流程都会在AMS进程中进行的,由一开始Launcher进程接收点击图标事件,先后经历了Launcher进程 -> AMS进程,最后进入了待启动应用程序进程,现在已经进入了第三个步骤,在目标应用程序进程中启动Activity。

扫描二维码关注公众号,回复: 5796446 查看本文章

步骤三:ActivityThread启动指定根Activity

上面步骤最后一个入口是app.thread.scheduleLaunchActivity(),那么就来看一下app.thread.scheduleLaunchActivity()

1.app.thread.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) {

            updateProcessState(procState, false);
		    	//1. 将Activity的启动参数全部封装给Activity。
            ActivityClientRecord r = new ActivityClientRecord();

            r.token = token;
            r.ident = ident;
            r.intent = intent;
            r.referrer = referrer;
            r.voiceInteractor = voiceInteractor;
            ...

            r.overrideConfig = overrideConfig;
            updatePendingConfiguration(curConfig);
				//2. 然后调用sendMessage()向H发送一个H.LAUNCH_ACTIVITY消息,并将ActivityClientRecord传递过去
            sendMessage(H.LAUNCH_ACTIVITY, r);
        }

2.sendMessage()

H 是ActivityThread的一个内部类,继承自Handler,用于处理ActivityThread的消息,由于ApplicationThread是一个Binder,运行在Binder线程池中,所以需要通过H将代码逻辑切换到主线程。

private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) {
            msg.setAsynchronous(true);
        }
        mH.sendMessage(msg);
    }

3.看主线程如何处理H.LAUNCH_ACTIVITY消息

public void handleMessage(Message msg) {
            switch (msg.what) {
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    //1. 首先将Activity的启动参数封装类ActivityClientRecord取出来
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    
						//2. 获取LoadApk类型的对象并赋值给ActivityClientRecord的成员变量r.packageInfo,应用程序进程要启动Activity时需要将该Activity所属的Apk加载进来。
                    r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
                    
                    //3. 调用handleLaunchActivity()去启动Activity
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
                
                ....

4. handleLaunchActivity()

private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
        ...
        WindowManagerGlobal.initialize();
		// 1. 启动Activity	
        Activity a = performLaunchActivity(r, customIntent);

        if (a != null) {
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            Bundle oldState = r.state;
            //2 .将Activity的状态设置为Resume
            handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);

            if (!r.activity.mFinished && r.startsNotResumed) {
                performPauseActivityIfNeeded(r, reason);

                if (r.isPreHoneycomb()) {
                    r.state = oldState;
                }
            }
        } else {
            // 发生异常,则调用AMS去finish这个Activity
            try {
                ActivityManager.getService().finishActivity(r.token, Activity.RESULT_CANCELED, null,Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        }
    }

5. performLaunchActivity()

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
		//获取ActivityInfo类,用于存储代码以及AndroidManifest.xml设置的Activity和Receiver节点信息,例如Activity的theme和launchMode
        ActivityInfo aInfo = r.activityInfo;
        //2.获取packageInfo 
        if (r.packageInfo == null) {
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,Context.CONTEXT_INCLUDE_CODE);
        }
        //3.获取ComponentName,保存了Activity的包名和类名
        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);
        }
		//4. 创建要启动Activity的上下文环境	
        ContextImpl appContext = createBaseContextForActivity(r);
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            
            //5. 用类加载器来创建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);
            }
        }	
        ...
        
        try {
        	 //6.创建Application,内部会调用Application的onCreate()方法
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);   

            if (activity != null) {
            
                ...
                appContext.setOuterContext(activity);
                
                //7.初始化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, r.configCallback);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                
                //8.调用mInstrumentation.callActivityOnCreate()来启动Activity
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }

				...
				return activity;
				
}
						

6. mInstrumentation.callActivityOnCreate()

public void callActivityOnCreate(Activity activity, Bundle icicle,PersistableBundle persistentState) {
        prePerformCreate(activity);
        activity.performCreate(icicle, persistentState); //这里调用了activity的onCreate()方法
        postPerformCreate(activity);
    }
    
    

7.Activity的生命周期函数onCreate()调用入口

final void performCreate(Bundle icicle) {
        restoreHasCurrentPermissionRequest(icicle);
        onCreate(icicle); //这里调用了Activity的onCreate(),开始了Activity的生命周期,应用程序也因此启动了。
        mActivityTransitionState.readState(icicle);
        performCreateCommon();
  }

总结:

从上面的步骤来看,Activity的启动过程涉及到多个进程,分别是Zygote进程、SystemServer进程、Launcher进程、应用程序进程,如图所示:

在这里插入图片描述

那么如果是普通的Activity启动涉及多少进程呢?明显是2个,因为不需要接触到Launcher和zygote

猜你喜欢

转载自blog.csdn.net/qq_26984087/article/details/89045921