Android 6.0 Launcher 启动 Activity 过程源码分析(三)

目录

技术答疑,成长进阶,可以加入我的知识星球:音视频领域专业问答的小圈子

Android 6.0 Launcher 启动 Activity 过程源码分析(二) 分析完了对待启动 Activity 组件的验证过程,获得组件信息,以及 ActivityRecord 添加至栈顶,将其他 Activity 进入中止状态,最后将待启动的 Activity 组件进入 Resumed状态,然而,由于待启动的 Activity 组件的应用程序进程尚未启动,最后执行 startSpecificActivityLocked方法创建进程。

ActivityStackSupervisor 类的 startSpecificActivityLocked() 方法

 1 void startSpecificActivityLocked(ActivityRecord r,
 2            boolean andResume, boolean checkConfig) {
 3        // Is this activity's application already running?
 4        ProcessRecord app = mService.getProcessRecordLocked(r.processName,
 5                r.info.applicationInfo.uid, true);
 6
 7        r.task.stack.setLaunchTime(r);
 8		
 9        if (app != null && app.thread != null) {
10            try {
11                if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
12                        || !"android".equals(r.info.packageName)) {
13                    app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
14                            mService.mProcessStats);
15                }
16                realStartActivityLocked(r, app, andResume, checkConfig);
17                return;
18            } catch (RemoteException e) {
19            }
20        }
21		// 进程尚未启动,app 为 null 。
22        mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
23                "activity", r.intent.getComponent(), false, false, true);
24    }
JAVA

在 ActivityManagerService 中,每一个 Activity 组件都有一个用户 ID 和一个进程名称,其中,用户 ID 是在安装该 Activity 组件时由 PackageManagerService 分配的,而进程名称则是由该 Activity 组件的 android:process属性来决定的。ActivityManagerService 在启动一个 Activity 组件时,首先会以它的用户 ID 和进程名称来检查系统中是否存在一个对应的应用程序进程。如果存在,就会直接通知这个应用程序进程将 Activity 组件启动起来;否则,就会先以这个用户 ID 和进程名称来创建一个应用程序进程,然后在通知这个应用程序进程将该 Activity 组件启动起来。

由于应用程序进程尚未启动,则 app 为 null ,mService 变量为 ActivityManagerService 。执行 startProcessLocked方法。

ActivityManagerService类的 startProcessLocked() 方法

 1 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
 2            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
 3            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
 4            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
 5        long startTime = SystemClock.elapsedRealtime();
 6        ProcessRecord app;
 7        if (!isolated) { // 传入的 isolated 参数为 false ,if 成立,并不是隔离的进程
 8	        // 根据进程名称和用户 ID 得到应用程序进程,由于不存在,则为 null 。
 9            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
10            checkTime(startTime, "startProcess: after getProcessRecord");
11			// 省略部分代码
12        } else {
13            // If this is an isolated process, it can't re-use an existing process.
14            app = null;
15        }
16		// 当进程已经被分配的 PID 时,
17		if (app != null && app.pid > 0) {
18		}
19		// 应用程序进程不存在,创建新的进程
20		if (app == null) {
21            checkTime(startTime, "startProcess: creating new process record");
22            // 创建应用程序进程
23            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
24            if (app == null) {
25            }
26            app.crashHandler = crashHandler;
27            checkTime(startTime, "startProcess: done creating new process record");
28        } else {
29            // If this is a new package in the process, add the package to the list
30            app.addPackage(info.packageName, info.versionCode, mProcessStats);
31            checkTime(startTime, "startProcess: added package to existing proc");
32        }
33		// 创建应用程序进程后,最终调用 startProcessLocked 方法
34		startProcessLocked(
35                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
JAVA

ActivityManagerService 类的 startProcessLocked方法重载了多个形式,最终执行了上述的函数。

由于并不是隔离的进程,首先会根据进程名称和用户 ID 检查应用程序是否存在,由于不存在,app 为 null ,则创建了新的应用程序进程,通过newProcessRecordLocked方法。最后还是调用了 startProcessLocked 方法。

ActivityManagerService类的 newProcessRecordLocked() 方法

 1final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
 2            boolean isolated, int isolatedUid) {
 3        String proc = customProcess != null ? customProcess : info.processName;
 4        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
 5        final int userId = UserHandle.getUserId(info.uid);
 6        int uid = info.uid;
 7        if (isolated) {
 8          // 省略与隔离进程相关代码
 9        }
10        final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11        if (!mBooted && !mBooting
12                && userId == UserHandle.USER_OWNER
13                && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
14            r.persistent = true;
15        }
16        addProcessNameLocked(r);
17        return r;
18    }
JAVA

通过 ApplicationInfo 创建了一个 ProcessRecord 。

ActivityManagerService类的 startProcessLocked() 方法

当创建完 ProcessRecord 后,最后还是调用了 startProcessLocked方法来创建一个进程 Process

 1private final void startProcessLocked(ProcessRecord app, String hostingType,
 2            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
 3		// 省略部分代码
 4	    // Start the process.  It will either succeed and return a result containing
 5        // the PID of the new process, or else throw a RuntimeException.
 6        // 在之前的函数调用中,entryPoint 参数为 null,则赋值为 android.app.ActivityThread 。
 7        boolean isActivityProcess = (entryPoint == null);
 8            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
 9        // 创建一个进程
10        Process.ProcessStartResult startResult = Process.start(entryPoint,
11                app.processName, uid, uid, gids, debugFlags, mountExternal,
12                app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
13                app.info.dataDir, entryPointArgs);
14
15		// 省略部分代码
16		 app.setPid(startResult.pid);
17            app.usingWrapper = startResult.usingWrapper;
18            app.removed = false;
19            app.killed = false;
20            app.killedByAm = false;
21            checkTime(startTime, "startProcess: starting to update pids map");
22            synchronized (mPidsSelfLocked) {
23            // app 类型为 ProcessRecord
24            // 将 ProcessRecord 对象保存在 ActivityManagerService 类的成员变量 mPidsSelfLocked 中
25                this.mPidsSelfLocked.put(startResult.pid, app);
26                if (isActivityProcess) {
27                // 向 ActivityManagerService 所运行的线程的消息队列发送 PROC_START_TIMEOUT_MSG 类型的消息
28                // 并指定这个消息在 PROC_START_TIMEOUT 毫秒后处理
29                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
30                    msg.obj = app;
31                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
32                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
33                }
34            }
35}
JAVA

调用 Process 类的静态成员函数start来启动一个新的应用程序进程。

新的应用程序进程创建完成后,当前进程就会得到一个大于 0 的进程 ID ,保存在变量 pid中,接着就以变量 pid为关键字将参数 app 所指向的一个 ProcessRecord 对象保存在 ActivityManagerService 类的成员变量 mPidsSelfLocked中。

最后,当新的进程启动完后,还需要向 ActivityManagerService 发送一个通知,以便 ActivityManagerService 可以在它里面启动一个 Service 组件,否则,ActivityManagerService 会认为它超时了,因此,不能将 Activity 组件启动起来。

ActivityThread 类的 main() 方法

由于 Process 类的静态方法 start 的第一个参数指明了进程进入点,则 ActivityThread 的 main 方法为一个进程的开始点。

 1public final class ActivityThread {
 2   final ApplicationThread mAppThread = new ApplicationThread();
 3   public static void main(String[] args) {
 4	   // 初始化主线程的消息队列
 5	   Looper.prepareMainLooper();
 6       ActivityThread thread = new ActivityThread();
 7       thread.attach(false);
 8	
 9	   if (sMainThreadHandler == null) {
10            sMainThreadHandler = thread.getHandler();
11       }
12       // 开启消息循环
13       Looper.loop();
14   }
15   
16   private void attach(boolean system) {
17        sCurrentActivityThread = this;
18        mSystemThread = system;
19        if (!system) { // 是否为系统进程
20            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
21                                                    UserHandle.myUserId());
22            RuntimeInit.setApplicationObject(mAppThread.asBinder());
23            // 获得 ActivityManagerService 的代理对象
24            final IActivityManager mgr = ActivityManagerNative.getDefault();
25            try {
26                mgr.attachApplication(mAppThread);
27            } catch (RemoteException ex) {
28                // Ignore
29            }
30     
31        } else {
32		   // 省略系统进程代码
33        } 
34		// 省略 ViewRootImpl 相关代码
35    }
36}
37
38// ActivityManagerProxy 的 attachApplication 方法
39    public void attachApplication(IApplicationThread app) throws RemoteException
40    {
41        Parcel data = Parcel.obtain();
42        Parcel reply = Parcel.obtain();
43        data.writeInterfaceToken(IActivityManager.descriptor);
44        data.writeStrongBinder(app.asBinder());
45        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
46        reply.readException();
47        data.recycle();
48        reply.recycle();
49    }
JAVA

新的应用程序启动时,在 main 方法里主要做了两件事情:

  • 在新的进程里面创建一个 ActivityThread 对象,并且调用它的成员函数 attach 向 ActivityManagerService 发送一个启动完成通知。
  • 调用 Looper 类的静态成员函数prepareMainLooper创建一个消息循环,并且在向 ActivityManagerService 发送启动完成通知之后,使得当前进程进入到这个消息循环中。

在 ActivityThread 对象内还创建了一个 ApplicationThread 对象,在之前提到过 ApplicationThread 是一个 Binder 本地对象,ActivityManagerService 就是通过它来和应用程序通信的。

attach方法内部通过 ActivityManagerNative.getDefault()得到了 ActivityManagerService 的代理对象 ActivityManagerProxyActivityManagerProxy通过 Binder 驱动发起一个类型为 ATTACH_APPLICATION_TRANSACTION的进程间通信。接下来就是 ActivityManagerService 响应这个通信。

ActivityManagerService类的 attachApplication() 方法

1    public final void attachApplication(IApplicationThread thread) {
2        synchronized (this) {
3            int callingPid = Binder.getCallingPid();
4            final long origId = Binder.clearCallingIdentity();
5            attachApplicationLocked(thread, callingPid);
6            Binder.restoreCallingIdentity(origId);
7        }
8    }
JAVA

接下来执行 attachApplicationLocked方法。

ActivityManagerService类的 attachApplicationLocked() 方法

  1private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
  2		ProcessRecord app;
  3        if (pid != MY_PID && pid >= 0) {
  4            synchronized (mPidsSelfLocked) {
  5                app = mPidsSelfLocked.get(pid);
  6            }
  7        } else {
  8            app = null;
  9        }
 10
 11	   final String processName = app.processName;
 12	   try {
 13            AppDeathRecipient adr = new AppDeathRecipient(
 14                    app, pid, thread);
 15            thread.asBinder().linkToDeath(adr, 0);
 16            app.deathRecipient = adr;
 17        } catch (RemoteException e) {
 18            app.resetPackageList(mProcessStats);
 19            startProcessLocked(app, "link fail", processName);
 20            return false;
 21        }
 22		app.makeActive(thread, mProcessStats);
 23        app.curAdj = app.setAdj = -100;
 24        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
 25        app.forcingToForeground = null;
 26        updateProcessForegroundLocked(app, false, false);
 27        app.hasShownUi = false;
 28        app.debugging = false;
 29        app.cached = false;
 30        app.killedByAm = false;
 31		
 32		// 移除超时消息,应用程序在规定时间内完成了启动。
 33        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
 34
 35		try{
 36		// 省略部分代码,跨进程调用 ActivityThread 的方法
 37			thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
 38                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
 39                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
 40                    enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent,
 41                    new Configuration(mConfiguration), app.compat,
 42                    getCommonServicesLocked(app.isolated),
 43                    mCoreSettingsObserver.getCoreSettingsLocked());
 44		}catch(Exception e){
 45			// 
 46		}
 47		boolean badApp = false;
 48        boolean didSomething = false;
 49		
 50		 // See if the top visible activity is waiting to run in this process...
 51		 // 调度 Activity
 52        if (normalMode) {
 53            try {
 54                if (mStackSupervisor.attachApplicationLocked(app)) {
 55                    didSomething = true;
 56                }
 57            } catch (Exception e) {
 58                badApp = true;
 59            }
 60        }
 61		// Find any services that should be running in this process...
 62		// 调度 Service
 63        if (!badApp) {
 64            try {
 65                didSomething |= mServices.attachApplicationLocked(app, processName);
 66            } catch (Exception e) {
 67                badApp = true;
 68            }
 69        }
 70        // Check if a next-broadcast receiver is in this process...
 71        // 调度 Broadcast 
 72        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
 73            try {
 74                didSomething |= sendPendingBroadcastsLocked(app);
 75            } catch (Exception e) {
 76                // If the app died trying to launch the receiver we declare it 'bad'
 77                badApp = true;
 78            }
 79        }
 80
 81
 82}
 83
 84// ApplicationThread 的 bindApplication 方法
 85public final void bindApplication(String processName, ApplicationInfo appInfo,
 86                List<ProviderInfo> providers, ComponentName instrumentationName,
 87                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
 88                IInstrumentationWatcher instrumentationWatcher,
 89                IUiAutomationConnection instrumentationUiConnection, int debugMode,
 90                boolean enableOpenGlTrace, boolean trackAllocation, boolean isRestrictedBackupMode,
 91                boolean persistent, Configuration config, CompatibilityInfo compatInfo,
 92                Map<String, IBinder> services, Bundle coreSettings) {
 93
 94            if (services != null) {
 95                // Setup the service cache in the ServiceManager
 96                ServiceManager.initServiceCache(services);
 97            }
 98            setCoreSettings(coreSettings);
 99            AppBindData data = new AppBindData();
100            data.processName = processName;
101            data.appInfo = appInfo;
102            data.providers = providers;
103            data.instrumentationName = instrumentationName;
104            data.instrumentationArgs = instrumentationArgs;
105            data.instrumentationWatcher = instrumentationWatcher;
106            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
107            data.debugMode = debugMode;
108            data.enableOpenGlTrace = enableOpenGlTrace;
109            data.trackAllocation = trackAllocation;
110            data.restrictedBackupMode = isRestrictedBackupMode;
111            data.persistent = persistent;
112            data.config = config;
113            data.compatInfo = compatInfo;
114            data.initProfilerInfo = profilerInfo;
115            // 向 ActivityThread 的应用程序主进程发送消息
116            sendMessage(H.BIND_APPLICATION, data);
117        }
JAVA

方法的参数 pid指向了前面所创建的应用程序进程的 PID ,在之前的步骤中,ActivityManagerService 以 PID 为关键字将一个 ProcessRecord 对象保存在了成员变量 mPidsSelfLocked 中,因此又通过该 PID 将 ProcessRecord 对象取回,保存在 app 变量中。

然后就对 app 变量进程赋值初始化,最重要的就是将应用程序进程的 ApplicationThread 对象赋值给 ProcessThread 的 thread 成员变量,这样 ActivityManagerService 就可以通过这个 ApplicationThread 代理对象和新创建的应用程序进程进行通信了。

接下来会执行 thread 的 bindApplication方法,该方法是一个跨进程通信了,因为 thread 是 ApplicationThread 类型。ActivityManagerService 正是通过它与 Activity 组件通信的。该方法的作用主要是将应用程序的一些信息发送给 Activity ,例如:ProfilerInfo之类的。

ApplicationThread内也响应了该方法,通过解析封装相应的数据,向主线程发送一个类型为BIND_APPLICATION的消息。

而在ActivityThread中也有一个类型为 H的 Handler ,继承自 Handler,用来处理主线程的消息循环。在 H类的handleMessage中通过handleBindApplication方法处理了类型为BIND_APPLICATION的消息。

ActivityManagerService 的信息传递给 ActivityThread 后,就可以开始调度了 Activity 组件了。通过 attachApplicationLocked方法调度 Activity 。

ActivityThread 类的 handleBindApplication() 方法

 1private void handleBindApplication(AppBindData data) {
 2
 3	// send up app name; do this *before* waiting for debugger
 4	// 设置进程名
 5        Process.setArgV0(data.processName);
 6    // 创建 Android 运行环境 Context .
 7    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
 8
 9	// 初始化 Intrumentation 对象
10	if (data.instrumentationName != null) {
11		try {
12	       java.lang.ClassLoader cl = instrContext.getClassLoader();
13	       mInstrumentation = (Instrumentation)
14	                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
15	       } catch (Exception e) {
16	       }
17	       mInstrumentation.init(this, instrContext, appContext,
18                   new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,
19                   data.instrumentationUiAutomationConnection);
20	 } else {
21            mInstrumentation = new Instrumentation();
22     }
23
24	 // Allow disk access during application and provider setup. This could
25     // block processing ordered broadcasts, but later processing would
26     // probably end up doing the same disk access.
27 
28        try {
29            // If the app is being launched for full backup or restore, bring it up in
30            // a restricted environment with the base application class.
31            // 创建 Application 对象
32            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
33            mInitialApplication = app;
34
35            // don't bring up providers in restricted mode; they may depend on the
36            // app's custom Application class
37            if (!data.restrictedBackupMode) {
38                List<ProviderInfo> providers = data.providers;
39                if (providers != null) {
40                    installContentProviders(app, providers);
41                    // For process that contains content providers, we want to
42                    // ensure that the JIT is enabled "at some point".
43                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
44                }
45            }
46
47            // Do this after providers, since instrumentation tests generally start their
48            // test thread at this point, and we don't want that racing.
49            try {
50                mInstrumentation.onCreate(data.instrumentationArgs);
51            }
52            catch (Exception e) {         
53            }
54            try {
55            // 执行 Application 的 onCreate 方法
56                mInstrumentation.callApplicationOnCreate(app);
57            } catch (Exception e) {
58            }
59        } finally {
60        }
61}
JAVA

系统进程将很多与应用程序进程相关的信息传递至此进行绑定,就是为了初始化一个 Android 应用程序的运行信息。

  • 初始化了运行环境上下文 Context 。
  • 初始化了 Instrumentation 。
  • 初始化了 Application 类。
  • 调用了 Application 的 onCreate 方法。

当把这些信息传递给 Activity 组件,并且初始化结束后,新的一个进程就蜕变成了 Android 进程了。

StackSupervisor 类的 attachApplicationLocked() 方法

 1 boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
 2        final String processName = app.processName;
 3        boolean didSomething = false;
 4        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
 5            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
 6            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
 7                final ActivityStack stack = stacks.get(stackNdx);
 8                if (!isFrontStack(stack)) {
 9                    continue;
10                }
11                ActivityRecord hr = stack.topRunningActivityLocked(null);
12                if (hr != null) {
13                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
14                            && processName.equals(hr.processName)) {
15                        try {
16                            if (realStartActivityLocked(hr, app, true, true)) {
17                                didSomething = true;
18                            }
19                        } catch (RemoteException e) {
20                            throw e;
21                        }
22                    }
23                }
24            }
25        }
26        if (!didSomething) {
27            ensureActivitiesVisibleLocked(null, 0);
28        }
29        return didSomething;
30    }
JAVA

遍历 ActivityStack 和 TaskRecord,找到位于 Activity 堆栈顶端的一个 ActivityRecord 对象 hr,接着检查这个 Activity 组件的用户 ID 和 进程名是否与 ProcessRecord 对象 app 所描述的应用程序的用户 ID 和进程名一致,如果一致,则调用 realStartActivityLocked方法来请求该应用程序进程启动一个 Activity 组件。

StackSupervisor 类的 realStartActivityLocked() 方法

 1    final boolean realStartActivityLocked(ActivityRecord r,
 2            ProcessRecord app, boolean andResume, boolean checkConfig)
 3            throws RemoteException {
 4
 5		r.app = app;
 6        app.waitingToKill = null;
 7        r.launchCount++;
 8        r.lastLaunchTime = SystemClock.uptimeMillis();
 9        
10        int idx = app.activities.indexOf(r);
11        if (idx < 0) {
12            app.activities.add(r);
13        }
14        
15	    try {
16		    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
17                    System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
18                    new Configuration(stack.mOverrideConfig), r.compat, r.launchedFromPackage,
19                    task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results,
20                    newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
21        } catch (RemoteException e) {
22        }
23        return true;
24  }
25// ApplicationThread 的 scheduleRelaunchActivity 方法
26 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
27                ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
28                CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
29                int procState, Bundle state, PersistableBundle persistentState,
30                List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
31                boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
32
33            updateProcessState(procState, false);
34
35            ActivityClientRecord r = new ActivityClientRecord();
36
37            r.token = token;
38            r.ident = ident;
39            r.intent = intent;
40            r.referrer = referrer;
41            r.voiceInteractor = voiceInteractor;
42            r.activityInfo = info;
43            r.compatInfo = compatInfo;
44            r.state = state;
45            r.persistentState = persistentState;
46
47            r.pendingResults = pendingResults;
48            r.pendingIntents = pendingNewIntents;
49
50            r.startsNotResumed = notResumed;
51            r.isForward = isForward;
52
53            r.profilerInfo = profilerInfo;
54
55            r.overrideConfig = overrideConfig;
56            updatePendingConfiguration(curConfig);
57			// 向主线程发送消息
58            sendMessage(H.LAUNCH_ACTIVITY, r);
59        }
JAVA

首先将参数 r的成员变量app的值设置为参数app,表示它描述的 Activity 组件是在参数 app 所描述的应用程序进程中启动的,接着将该 Activity 组件添加到参数 app所描述的应用程序进程的 Activity 组件列表中。

接下来调用threadscheduleLaunchActivity方法来通知前面创建的应用程序进程启动由参数r所描述的一个 Activity 组件。

由于 thread的类型是 ApplicationThread,又是一个 Binder 对象,则又是跨进程的通信,此时的执行还是在 ActivityManagerService 进程内的。通过 ApplicationThread 跨进程向应用程序进程发送请求。

在主线程的消息循环中对应的响应方法为handleLaunchActivity

ActivityThread 类的 handleLaunchActivity() 方法

 1private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
 2
 3		 // Initialize before creating the activity
 4        WindowManagerGlobal.initialize();
 5        Activity a = performLaunchActivity(r, customIntent);
 6
 7		if (a != null) {
 8            r.createdConfig = new Configuration(mConfiguration);
 9            Bundle oldState = r.state;
10            handleResumeActivity(r.token, false, r.isForward,
11                    !r.activity.mFinished && !r.startsNotResumed);
12		} else {
13            // If there was an error, for any reason, tell the activity
14            // manager to stop us.
15            try {
16                ActivityManagerNative.getDefault()
17                    .finishActivity(r.token, Activity.RESULT_CANCELED, null, false);
18            } catch (RemoteException ex) {
19                // Ignore
20            }
21        }
JAVA

首先调用了performLaunchActivity将 Activity 组件启动起来,然后在调用 handleResumeActivity方法将 Activity 组件的状态设置为 Resumed

ActivityThread 类的 performLaunchActivity() 方法

 1private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
 2
 3	ComponentName component = r.intent.getComponent();
 4        if (component == null) {
 5            component = r.intent.resolveActivity(
 6                mInitialApplication.getPackageManager());
 7            r.intent.setComponent(component);
 8        }
 9    // 通过反射 新建一个 Activity 对象
10	Activity activity = null;
11        try {
12            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
13            activity = mInstrumentation.newActivity(
14                    cl, component.getClassName(), r.intent);
15            StrictMode.incrementExpectedActivityCount(activity.getClass());
16            r.intent.setExtrasClassLoader(cl);
17            r.intent.prepareToEnterProcess();
18            if (r.state != null) {
19                r.state.setClassLoader(cl);
20            }
21        } catch (Exception e) {
22        }
23
24        try {
25            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
26            if (activity != null) {
27	            // 创建 Context ,作为 Activity 的运行上下文环境
28                Context appContext = createBaseContextForActivity(r, activity);
29                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
30                Configuration config = new Configuration(mCompatConfiguration);
31                
32                activity.attach(appContext, this, getInstrumentation(), r.token,
33                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
34                        r.embeddedID, r.lastNonConfigurationInstances, config,
35                        r.referrer, r.voiceInteractor);
36                        
37                if (r.isPersistable()) { // 回调 Activity 的 onCreate 函数
38                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
39                } else {
40                    mInstrumentation.callActivityOnCreate(activity, r.state);
41                }
42              
43                r.activity = activity;
44                r.stopped = true;
45                if (!r.activity.mFinished) { // 回调 Activity 的 onStart 函数
46                    activity.performStart();
47                    r.stopped = false;
48                }
49                if (!r.activity.mFinished) { // Activity 的 onRestoreInstanceState 函数
50                    if (r.isPersistable()) {
51                        if (r.state != null || r.persistentState != null) {
52                            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
53                                    r.persistentState);
54                        }
55                    } else if (r.state != null) {
56                        mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
57                    }
58                }
59              
60            }
61            r.paused = true;
62            mActivities.put(r.token, r);
63        } catch (SuperNotCalledException e) {
64            throw e;
65        } catch (Exception e) {
66        }
67}
JAVA

首先获得要启动的 Activity 组件的包名和类名,它们使用一个ComponentName对象 component 来描述。

接着通过反射创建一个 Activity 类实例。然后,初始化了一个 Context 对象,作为前面创建的 Android 类实例的运行环境上下文,通过它就能访问特定的应用程序资源,再调用 attach方法,初始化 Activity 相关信息。

再调用Instrumentation类的callActivityOnCreate方法将 Activity 启动起来,此时,Activity 的 onCreate 方法就会被调用了,接下来就是调用 performStart方法,方法内部调用Instrumentation类的callActivityOnStart方法调用 Activity 的 onStart 方法。此时,Activity 的 onCreate 和 onStart 两大方法都调用了。

接下来就是执行handleResumeActivity方法将 Activity 组件的状态设置为 Resumed

ActivityThread 类的 handleResumeActivity() 方法

 1 final void handleResumeActivity(IBinder token,
 2            boolean clearHide, boolean isForward, boolean reallyResume) {
 3
 4	 // TODO Push resumeArgs into the activity for consideration
 5	 // 真正执行的是 performResumeActivity 方法
 6        ActivityClientRecord r = performResumeActivity(token, clearHide);
 7        if (r != null) {
 8	        // 省略和 Window 相关代码
 9        } else {
10	        try {
11                ActivityManagerNative.getDefault()
12                    .finishActivity(token, Activity.RESULT_CANCELED, null, false);
13            } catch (RemoteException ex) {
14            }
15        }
16}
JAVA

真正执行的是 performResumeActivity方法。

ActivityThread 类的 performResumeActivity() 方法

1    public final ActivityClientRecord performResumeActivity(IBinder token,
2            boolean clearHide) {
3             ActivityClientRecord r = mActivities.get(token);
4             if (r != null && !r.activity.mFinished) {
5	             r.activity.performResume();
6	         }
7	         return r ;
8	}
JAVA

最后,performResume方法还是调用的Instrumentation类的 callActivityOnResume方法,让当前 Activity 组件进入了 Resumed状态。

至此,从 Launcher 组件启动 Activity 过程源码分析就算是过了一遍了,里面还有许多细节之处,等待日后挖掘。

参考

  1. Android 6.0 源码
  2. 《Android 系统源代码情景分析》
  3. http://duanqz.github.io/2016-07-29-Activity-LaunchProcess-Part1

欢迎关注微信公众号:音视频开发进阶

Licensed under CC BY-NC-SA 4.0
粤ICP备20067247号
使用 Hugo 构建    主题 StackedJimmy 设计,Jacob 修改