更新:
2016-10-29:更新handleBindApplication部分。
我这个版本的原则是,有话则长,无话则短.
以下分析基于6.0.1_r10版本。
先看一张大图:
1. 桌面的onClick事件(进程:桌面应用的进程)
我们暂时忽略Input处理的过程,以桌面的onClick事件被触发为起点。
这部分根据Launcher的不同而大同小异。
2. ActivityManagerService之startActivity(进程AmS)
路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
桌面调用framework,最后会调到AmS的startActivity方法.
现在是多用户时代了,startActivity现在唯一做的事儿,就是通过UserHandle.getCallingUserId()去获取当前的user id,然后调用startActivityAsUser方法。
3848 @Override
3849 public final int startActivity(IApplicationThread caller, String callingPackage,
3850 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3851 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3852 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3853 resultWho, requestCode, startFlags, profilerInfo, options,
3854 UserHandle.getCallingUserId());
3855 }
3. ActivityManagerService之startActivityAsUser
这个方法如其名,还真是只处理跟user相关的工作,调用handleIncomingUser。
之后,调用ActivityStackSupervisor来去处理跟Activity状态相关真正逻辑。
3857 @Override
3858 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3859 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3860 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3861 enforceNotIsolatedCaller("startActivity");
3862 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3863 false, ALLOW_FULL_ONLY, "startActivity", null);
3864 // TODO: Switch to user app stacks here.
3865 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3866 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3867 profilerInfo, null, null, options, false, userId, null, null);
3868 }
4. ActivityStackSupervisor之startActivityMayWait(进程AmS)
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
先解释一下为什么叫MayWait,因为调用startActivity是可能要等待结果的startActivityForResult,那就要挂起调用者。
首先,startActivityMayWait要读取一些信息。从4.4开始,这部分逻辑写到resolveActivity方法中,它会调用PackageManagerService的resolveIntent方法。这个方法会先调用queryIntentActivities方法出查询相关的列表,然后再调用chooseBestActivity方法去选择。为了不影响主线,这些支线内容后面再讲。
主线往下走,进入startActivityLocked。Locked意思是调用者需要保证加锁保护,不能重复调用,在startActivityMayWait中,是采用mService对象,也就是构造ActivityStackSupervisor时传进来的ActivityManagerService的对象。
调用成功了之后,如果需要wait,就让mService.wait()去等待吧。新Activity还在征途上。
925 final int startActivityMayWait(IApplicationThread caller, int callingUid,
926 String callingPackage, Intent intent, String resolvedType,
927 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
928 IBinder resultTo, String resultWho, int requestCode, int startFlags,
929 ProfilerInfo profilerInfo, WaitResult outResult, Configuration config,
930 Bundle options, boolean ignoreTargetSecurity, int userId,
931 IActivityContainer iContainer, TaskRecord inTask) {
...
941 // Collect information about the target of the Intent.
942 ActivityInfo aInfo =
943 resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
...
1045 int res = startActivityLocked(caller, intent, resolvedType, aInfo,
1046 voiceSession, voiceInteractor, resultTo, resultWho,
1047 requestCode, callingPid, callingUid, callingPackage,
1048 realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity,
1049 componentSpecified, null, container, inTask);
...
5. ActivityStackSupervisor之startActivityLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
前面先做一系列检查的工作,比如权限,比如Intent防火墙检查。
准备做好之后,就new一个ActivityRecord,用于存储Activity的各种状态和历史信息。
然后,通过getFocusedStack方法获取当前获取焦点的ActivityStack。ActivityStackSupervisor中的mFocusedStack中保存了当前的前台ActivityStack。
下面就准备切换新进程了,先判断一下是否可以切换,如果处于通话中界面等无法马上切换的情况。通过ActivityManagerService的checkAppSwitchAllowedLocked方法来做检查,如果当前不允许做进程切换,就先存到PendingActivityLaunch的列表中,等待以后有机会再调用。
如果允许做切换,那么先检查一下当前是否有以前的等待任务,如果有就先执行它们,调用doPendingActivityLaunchesLocked方法去执行这个循环。
如果以上都完成了,就调用startActivityUncheckedLocked。
1399 final int startActivityLocked(IApplicationThread caller,
1400 Intent intent, String resolvedType, ActivityInfo aInfo,
1401 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
1402 IBinder resultTo, String resultWho, int requestCode,
1403 int callingPid, int callingUid, String callingPackage,
1404 int realCallingPid, int realCallingUid, int startFlags, Bundle options,
1405 boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
1406 ActivityContainer container, TaskRecord inTask) {
...
1675 err = startActivityUncheckedLocked(r, sourceRecord, voiceSession, voiceInteractor,
1676 startFlags, true, options, inTask);
1677
1678 if (err < 0) {
1679 // If someone asked to have the keyguard dismissed on the next
1680 // activity start, but we are not actually doing an activity
1681 // switch... just dismiss the keyguard now, because we
1682 // probably want to see whatever is behind it.
1683 notifyActivityDrawnForKeyguard();
1684 }
1685 return err;
1686 }
6. ActivityStackSupervisor之startActivityUncheckedLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
通过一系列分析,找到了该执行的目标ActivityStack,然后调用该ActivityStack的startActivityLocked方法针对该任务做具体的操作。
1828 final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
1829 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, int startFlags,
1830 boolean doResume, Bundle options, TaskRecord inTask) {
...
2457 ActivityStack.logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
2458 targetStack.mLastPausedActivity = null;
2459 targetStack.startActivityLocked(r, newTask, doResume, keepCurTransition, options);
2460 if (!launchTaskBehind) {
2461 // Don't set focus on an activity that's going to the back.
2462 mService.setFocusedActivityLocked(r, "startedActivity");
2463 }
2464 return ActivityManager.START_SUCCESS;
2465 }
7. ActivityStack之startActivityLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
如果需要的话,这一步中会调用到WmS的setAppStartingWindow,开始准备新应用的启动窗口。
这其中,有重要一步是调用WindowManagerService的addAppToken方法去将信息共步给WmS,为下一步的显示做准备。
最后,调用ActivityStackSupervisor的resumeTopActivitiesLocked方法,将显示的Activities都resume一下。
2074 final void startActivityLocked(ActivityRecord r, boolean newTask,
2075 boolean doResume, boolean keepCurTransition, Bundle options) {
...
2232 if (doResume) {
2233 mStackSupervisor.resumeTopActivitiesLocked(this, r, options);
2234 }
2235 }
8. ActivityStackSupervisor之resumeTopActivitiesLocked
先获取当前焦点显示的ActivityStack,调其resumeTopActivityLocked。完成后,遍历所有能显示的Activity的stack。
2727 boolean resumeTopActivitiesLocked(ActivityStack targetStack, ActivityRecord target,
2728 Bundle targetOptions) {
2729 if (targetStack == null) {
2730 targetStack = mFocusedStack;
2731 }
2732 // Do targetStack first.
2733 boolean result = false;
2734 if (isFrontStack(targetStack)) {
2735 result = targetStack.resumeTopActivityLocked(target, targetOptions);
2736 }
2737
2738 for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
2739 final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
2740 for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
2741 final ActivityStack stack = stacks.get(stackNdx);
2742 if (stack == targetStack) {
2743 // Already started above.
2744 continue;
2745 }
2746 if (isFrontStack(stack)) {
2747 stack.resumeTopActivityLocked(null);
2748 }
2749 }
2750 }
2751 return result;
2752 }
9. ActivityStack之resumeTopActivityLocked
调用resumeTopActivityInnerLocked
1540 final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) {
1541 if (mStackSupervisor.inResumeTopActivity) {
1542 // Don't even start recursing.
1543 return false;
1544 }
1545
1546 boolean result = false;
1547 try {
1548 // Protect against recursion.
1549 mStackSupervisor.inResumeTopActivity = true;
1550 if (mService.mLockScreenShown == ActivityManagerService.LOCK_SCREEN_LEAVING) {
1551 mService.mLockScreenShown = ActivityManagerService.LOCK_SCREEN_HIDDEN;
1552 mService.updateSleepIfNeededLocked();
1553 }
1554 result = resumeTopActivityInnerLocked(prev, options);
1555 } finally {
1556 mStackSupervisor.inResumeTopActivity = false;
1557 }
1558 return result;
1559 }
10. ActivityStack之resumeTopActivityInnerLocked
这是第一次进入这个方法,这次我们是走pause桌面这一支,下一次我们就走到最后的startSpecificActivityLocked那一支。
调用startPausingLocked去pause。
1561 private boolean resumeTopActivityInnerLocked(ActivityRecord prev, Bundle options) {
...
1729 if (mResumedActivity != null) {
1730 if (DEBUG_STATES) Slog.d(TAG_STATES,
1731 "resumeTopActivityLocked: Pausing " + mResumedActivity);
1732 pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
1733 }
11. ActivityStack之startPausingLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
AmS开始发起pause桌面的操作
如果不是从桌面启动的话,就要去为上一个应用抓个用于显示在近期任务里的图。
prev.updateThumbnailLocked(screenshotActivities(prev), null);
处理完成之后,通知桌面应用去执行onPause。
prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,userLeaving, prev.configChangeFlags, dontWait);
这个thread就是IPC的ApplicationThreadNative对象。
802 /**
803 * Start pausing the currently resumed activity. It is an error to call this if there
804 * is already an activity being paused or there is no resumed activity.
805 *
806 * @param userLeaving True if this should result in an onUserLeaving to the current activity.
807 * @param uiSleeping True if this is happening with the user interface going to sleep (the
808 * screen turning off).
809 * @param resuming True if this is being called as part of resuming the top activity, so
810 * we shouldn't try to instigate a resume here.
811 * @param dontWait True if the caller does not want to wait for the pause to complete. If
812 * set to true, we will immediately complete the pause here before returning.
813 * @return Returns true if an activity now is in the PAUSING state, and we are waiting for
814 * it to tell us when it is done.
815 */
816 final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming,
817 boolean dontWait) {
...
860 if (prev.app != null && prev.app.thread != null) {
861 if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
862 try {
863 EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
864 prev.userId, System.identityHashCode(prev),
865 prev.shortComponentName);
866 mService.updateUsageStats(prev, false);
867 prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
868 userLeaving, prev.configChangeFlags, dontWait);
12. ApplicationThreadNative的schedulePauseActivity
路径:frameworks/base/core/java/android/app/ApplicationThreadNative.java
AmS要通过IPC来通知给桌面,于是通过Proxy来发送IPC操作.
718 public final void schedulePauseActivity(IBinder token, boolean finished,
719 boolean userLeaving, int configChanges, boolean dontReport) throws RemoteException {
720 Parcel data = Parcel.obtain();
721 data.writeInterfaceToken(IApplicationThread.descriptor);
722 data.writeStrongBinder(token);
723 data.writeInt(finished ? 1 : 0);
724 data.writeInt(userLeaving ? 1 :0);
725 data.writeInt(configChanges);
726 data.writeInt(dontReport ? 1 : 0);
727 mRemote.transact(SCHEDULE_PAUSE_ACTIVITY_TRANSACTION, data, null,
728 IBinder.FLAG_ONEWAY);
729 data.recycle();
730 }
13. ActivityThread之schedulePauseActivity (桌面进程)
路径:frameworks/base/core/java/android/app/ActivityThread.java
通过IPC,运行桌面应用的ActivityThread的schedulePauseActivity。此处ActivityThread会将这个请求放入队列中,等待运行。
588 public final void schedulePauseActivity(IBinder token, boolean finished,
589 boolean userLeaving, int configChanges, boolean dontReport) {
590 sendMessage(
591 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
592 token,
593 (userLeaving ? 1 : 0) | (dontReport ? 2 : 0),
594 configChanges);
595 }
在这段期间,WmS也没闲着,类似于之前我们在startActivityLocked时做的addWindow之类的操作一直在干活。
14. ActivityThread之handlePauseActivity (桌面进程)
终于从队列中轮到出场了,开始执行桌面的onPause吧。
不过先别急,执行onPause之前,先执行performUserLeavingActivity,最后会调到Activity的performUserLeaving。
这个方法做两步:
final void performUserLeaving() {
onUserInteraction();
onUserLeaveHint();
}
这些都做完了,调用performPauseActivity。
3305 private void handlePauseActivity(IBinder token, boolean finished,
3306 boolean userLeaving, int configChanges, boolean dontReport) {
...
3310 if (userLeaving) {
3311 performUserLeavingActivity(r);
3312 }
...
3315 performPauseActivity(token, finished, r.isPreHoneycomb());
...
3325 ActivityManagerNative.getDefault().activityPaused(token);
...
}
15. ActivityThread之performPauseActivity
首先判断一下状态,如果已经pause了,那就需要先resume之。当然,如果pause了之后正在finishing中,就算了,不是的话,抛个RuntimeException,问问调用者不先resume是为哪般。
没有异常的话,先调用callCallActivityOnSaveInstanceState,这个会通过Instrumentation的callActivityOnSaveInstanceState去调用Activity的performSaveInstanceState, 然后会调到Activity的onSaveInstanceState。还会将对话框的信息做保存操作。
保存完状态之后,再调用Instrumentation的callActivityOnPause。然后调用Activity的performPause。
Activity在onPause之前,先通知各个Fragment去onPause,再调用Activity的onPause.
performPauseActivity结束后,回到launchPauseActivity,下面通知AMS,调IPC来做activityPaused。
16. ActivityManagerNative 之activityPaused
路径:frameworks/base/core/java/android/app/ActivityManagerNative.java
桌面的onPause执行完了,通过IPC通知AmS,可以启动新应用了。
17. ActivityManagerService之activityPaused
路径:services/core/java/com/android/server/am/ActivityManagerService.java
AmS收到activityPaused的消息,然后找到对应的ActivityStack的activityPausedLocked。
18. ActivityStack之activityPausedLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
然后调用completePausedLocked。
19. ActivityStack之completePauseLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
到此,桌面的onPause正式告一段落。
结束之后,再次调用前面我们已经遇到过的ActivityStackSupervisor的resumeTopActivitiesLocked,前一次我们走了一半就调pause过程去了,这次我们将走到最后。
20. ActivityStackSupervisor之resumeTopActivitiesLocked
还跟上次一样,调相应的ActivityStack的resumeTopActivityLocked。
21. ActivityStack之resumeTopActivityLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStack.java
这个方法只是一个十几行的wrapper,除了设了个flag和处理锁屏之外,直接调用resumeTopActivityInnerLocked方法。
22. ActivityStack之resumeTopActivityInnerLocked
这个大方法走到最后,执行ActivityStackSupervisor的startSpecificActivityLocked。
(注:这个方法是5.0之后分出来的,4.4上还在resumeTopActivityLocked里面)
23. ActivityStackSupervisor之startSpecificActivityLocked (AmS进程)
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
从这里,又从ActivityStackSupervisor调回ActivityManagerService,调用startProcessLocked。
24. ActivityManagerService 之startProcessLocked
路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
通过调用android.os.Process的start去启动新进程。
25. Process.start
路径:frameworks/base/ core/java/android/os/Process.java
其实就是startViaZygote的一个简单封装。
481 public static final ProcessStartResult start(final String processClass,
482 final String niceName,
483 int uid, int gid, int[] gids,
484 int debugFlags, int mountExternal,
485 int targetSdkVersion,
486 String seInfo,
487 String abi,
488 String instructionSet,
489 String appDataDir,
490 String[] zygoteArgs) {
491 try {
492 return startViaZygote(processClass, niceName, uid, gid, gids,
493 debugFlags, mountExternal, targetSdkVersion, seInfo,
494 abi, instructionSet, appDataDir, zygoteArgs);
495 } catch (ZygoteStartFailedEx ex) {
496 Log.e(LOG_TAG,
497 "Starting VM process through Zygote failed");
498 throw new RuntimeException(
499 "Starting VM process through Zygote failed", ex);
500 }
501 }
26. Process.startViaZygote
路径:frameworks/base/core/java/android/os/Process.java
主要是处理参数,然后调用zygoteSendArgsAndGetResult去通过socket通信去通知zygote。
27. Process.zygoteSendArgsAndGetResult
路径:frameworks/base/core/java/android/os/Process.java
通过socket通知Zygote进程去fork新进程。接收方是ZygoteConnection。
28. ZygoteConnection.runOnce
路径:frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java
从socket中读取命令并执行。
这个可以往下再分为4步:
- readArgumentList
- apply security policies
- apply security policies
- preForkAndSpecialize
29. Zygote之forkAndSpecialize
路径:/frameworks/base/core/java/com/android/internal/os/Zygote.java
这步分为三个子步骤:
- preFork
- nativeForkAndSpecialize
- postForkCommon
29-1. ZygoteHooks.PreFork
路径:/libcore/dalvik/src/main/java/dalvik/system/ ZygoteHooks.java
这步离开了frameworks/base,进入了libcore。这里面要注意,不能调用Android的API,打个log什么的都要注意。
- Daemons.stop()
停掉GC,停掉finalizer等,fork进程时不需要这些 - waitUntilAllThreadsStopped()
确保fork之前只有一个线程在运行 - nativePreFork()
给虚拟机一个机会去在fork之前做点处理
29-2. com_android_internal_os_Zygote_nativeForkAndSpecialize
路径:/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
这是我们第一次进入C++层。真正做事的函数是ForkAndSpecializeCommon。
真正开始fork新进程
- SetSigChldHandler
- Fork and detach(新进程从这一步开始诞生)
- child process setup
这一步是值得大书特书的一步,因为从这一步开始,更具体地说是从Fork and detach开始,新应用的进程终于fork出来了。从此zygote老进程的事情我们不再关心,我们来看新进程号就好了。
Child process setup之后,有一个重要的函数会被执行到,这就是ZygoteHooks_nativePostForkChild。
在这个函数中,我们熟悉的AOC版本号的log会输出出来。
这个函数的AOC版本路径在:/aliyunos/aoc/vm/native/dalvik_system_ZygoteHooks.cc中。
#if defined(AOC_VERSION)
LOG(INFO) << "==========================";
LOG(INFO) << "+ AOC version " << Runtime::GetVersionString() << " +";
LOG(INFO) << "==========================";
#endif
对应的ART版本在:/art/runtime/native/dalvik_system_ZygoteHooks.cc中。
29-3. postForkCommon
路径:/libcore/dalvik/src/main/java/dalvik/system/ZygoteHooks.java
只干一件事,把preFork里面stop的monitor们重新打开。这一步要注意,原来的Zygote里面的不要去管了,只看新进程的就好。
30. RuntimeInit.zygoteInit
路径:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
31. RuntimeInit.invokeStaticMain
路径:frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
初始化完成,通过反射来调用ActivityThread的main方法
32. ActivityThread main
路径:frameworks/base/ core/java/android/app/ActivityThread.java
执行ActivityThread的main方法,新的应用正式上路
33. Proxy:attachApplication
路径:frameworks/base/
新的Activity建好了,要通知AmS,走IPC。
34. ActivityManagerService之attachApplication
路径: frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
AmS收到attach的通知,一切准备就绪。
35. AMS:attachApplicationLocked
路径:frameworks/base/ services/core/java/com/android/server/am/ActivityManagerService.java
其它部分都是线性的,这部分我们不得不分成两个部分各表一支了。这两部分分别走IPC,最后在ActivityThread的队列中汇合。
首先是bindApplication。
36. ApplicationThreadProxy之bindApplication
IPC调用
路径:frameworks/base/core/java/android/app/ApplicationThreadNative.java
37. ActivityThread之bindApplication
路径:frameworks/base/core/java/android/app/ActivityThread.java
主要包括两部分的操作,虽然这个方法不叫做scheduleXXX,但是实际上两步的操作都是放到队列中。
到这一步的时候,其实我们只是启动了一个空进程而己,跟实际的apk还一点关系也没有。
首先,如果services不为空的话,先初始化一下services cache。
ServiceManager.initServiceCache(services);
然后,schedule第一个任务,setCoreSettings(coreSettings);
这个最终会走到handleSetCoreSettings。
下面,PM才出场去读真正的package的信息。读好之后,再去将BIND_APPLICATION消息放到队列里去,这时候可能正在执行setCoreSettings。
38. ActivityThread之handleBindApplication
真正启动Activity之前,还得做一些准备工作。比如install provider就是在这时候做的。
38-1 LoadedApk之makeApplication
我们都知道,在Activity之外,对于每个应用,还对应一个Application类。这个Application就是在LoadApk的makeApplication方法时构造的。
554 public Application makeApplication(boolean forceDefaultAppClass,
555 Instrumentation instrumentation) {
556 if (mApplication != null) {
557 return mApplication;
558 }
559
560 Application app = null;
561
562 String appClass = mApplicationInfo.className;
563 if (forceDefaultAppClass || (appClass == null)) {
564 appClass = "android.app.Application";
565 }
下面调用ClassLoader,并且生成ApplicationContext.
567 try {
568 java.lang.ClassLoader cl = getClassLoader();
569 if (!mPackageName.equals("android")) {
570 initializeJavaContextClassLoader();
571 }
572 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
下面将通过Intrumentation的newApplication方法去真正创建Application
573 app = mActivityThread.mInstrumentation.newApplication(
574 cl, appClass, appContext);
575 appContext.setOuterContext(app);
576 } catch (Exception e) {
577 if (!mActivityThread.mInstrumentation.onException(app, e)) {
578 throw new RuntimeException(
579 "Unable to instantiate application " + appClass
580 + ": " + e.toString(), e);
581 }
582 }
583 mActivityThread.mAllApplications.add(app);
584 mApplication = app;
38-2 Application之newApplication
通过反射构造对象,然后调用Application的attach方法。
993 static public Application newApplication(Class<?> clazz, Context context)
994 throws InstantiationException, IllegalAccessException,
995 ClassNotFoundException {
996 Application app = (Application)clazz.newInstance();
997 app.attach(context);
998 return app;
999 }
38-3 Application之attach
attach再调用attachBaseContext。
183 /**
184 * @hide
185 */
186 /* package */ final void attach(Context context) {
187 attachBaseContext(context);
188 mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
189 }
```
### 38-4 ContextThemeWrapper之attachBaseContext
50 @Override
51 protected void attachBaseContext(Context newBase) {
52 super.attachBaseContext(newBase);
53 }
### 38-5 ContextWrapper的attachBaseContext
65 protected void attachBaseContext(Context base) {
66 if (mBase != null) {
67 throw new IllegalStateException("Base context already set");
68 }
69 mBase = base;
70 }
Application构造好之后,将调用Application的onCreate方法。
586 if (instrumentation != null) {
587 try {
588 instrumentation.callApplicationOnCreate(app);
589 } catch (Exception e) {
590 if (!instrumentation.onException(app, e)) {
591 throw new RuntimeException(
592 "Unable to create application " + app.getClass().getName()
593 + ": " + e.toString(), e);
594 }
595 }
596 }
最后更新所有R常量的值
598 // Rewrite the R 'constants' for all library apks.
599 SparseArray packageIdentifiers = getAssets(mActivityThread)
600 .getAssignedPackageIdentifiers();
601 final int N = packageIdentifiers.size();
602 for (int i = 0; i < N; i++) {
603 final int id = packageIdentifiers.keyAt(i);
604 if (id == 0x01 || id == 0x7f) {
605 continue;
606 }
607
608 rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);
609 }
610
611 return app;
612 }
下面花开两朵说另一枝,回到attachApplicationLocked方法,它将会调用到realStartActivityLocked。
### 39. ActivityStackSupervisor之realStartActivityLocked(AmS进程)
路径:frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java
这时算是真正启动,通过Activity,可以执行onCreate了。
### 40. ApplicationThreadNative之scheduleLaunchActivity
路径:frameworks/base/core/java/android/app/ApplicationThreadNative.java
IPC通道,通知本地进程
### 41. ActivityThread之scheduleLaunchActivity
路径:frameworks/base/ core/java/android/app/ActivityThread.java
ActivityThread收到,将命令放入队列。
### 42. ActivityThread之handleLaunchActivity
路径:frameworks/base/ core/java/android/app/ActivityThread.java
正式开始Activity的启动流程。
### 43. ActivityThread之performLaunchActivity
路径:frameworks/base/ core/java/android/app/ActivityThread.java
负责new出Activity的实例,makeApplication,然后调用Activity.attach向系统注册。
最后,通过callActivityOnCreate来调用应用的onCreate方法。
### 44. ActivityThread之handleResumeActivity
路径:frameworks/base/ core/java/android/app/ActivityThread.java
首先,通过performResumeActivity方法调用应用的onResume方法。
如大家所熟知的,执行完onResume之后,真正的绘制工作就才真正开始。
ActivityThread通过ViewManager对象调用其addView方法,开始正式通知WmS要添加窗口了。实际上,获取的这个ViewManager,是其子接口WindowManager的实现类WindowManagerImpl的方法。这个WindowManagerImpl的对象是通过
(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)调用从系统服务获取到的。
### 45. WindowManagerImpl之addView
路径:frameworks/base/core/java/android/view/WindowManagerImpl.java
ViewManager只是一个接口,用于定义功能,本身并不与WmS打交道。它通过单例对象WindowManagerGlobal去访问ViewRootImpl,再由ViewRootImpl去跟WmS通信。
### 46. WindowManagerGlobal之addView
路径:frameworks/base/core/java/android/view/WindowManagerGlobal.java
WindowManagerGlobal也只是个二传手,最终调用ViewRootImpl类的setView来真正与WmS交互。
### 47. ViewRootImpl之setView
路径:frameworks/base/core/java/android/view/ViewRootImpl.java
ViewRootImpl被构造出来后,会通过WindowManagerGlobal的getWindowSession方法去创建一个与WmS之间的连接。构造中会调到这一句:
mWindowSession = WindowManagerGlobal.getWindowSession();
在正式添加到WmS之前,首先要保证这个View树可以正常接收事件,于是先发起一次requestLayout。
### 48. ViewRootImpl之requestLayout
这个方法本身是WmS最简单的方法之一,先检查一下是不是UI线程,如果是,就scheduleTraversals,申请做一次遍历。
准备好了之后,setView就会通过mWindowSession去IPC通知WmS去添加一个窗口。
### 49. Session之addToDisplay
路径:frameworks/base/services/core/java/com/android/server/wm/Session.java
IPC调用WmS的addWindow方法。
### 50. WindowManagerService之addWindow
路径:frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
第一步先检查权限,比如部分系统窗口就不是应用可以添加的。
第二步去检查是不是重复添加了。
if (mWindowMap.containsKey(client.asBinder())) {
Slog.w(TAG, "Window " + client + " is already added");
return WindowManagerGlobal.ADD_DUPLICATE_ADD;
}
第三步,如果是子窗口,就寻找父窗口。
第四步,检查窗口的有效性。
第五步,用WindowState对象来管理窗口的状态。
win = new WindowState(this, session, client, token,attachedWindow, appOp0, seq, attrs, viewVisibility, displayContent);
第六步,调整Window属性
第七步,将token加入到mTokenMap中。
第八步,将client.asBinder()加到mWindowMap中。
第九步,将Window们按顺序排列,调用addWindowToListInOrderLocked方法。
这些做完,addView就算完成了,剩下的事情就看遍历的了。
### 51. ViewRootImpl之scheduleTraversals
准备好了之后,放入队列等待被遍历。
### 52. ViewRootImpl之doTraversal
遍历操作,实际逻辑都在performTraversals中。
### 53. ViewRootImpl之performTraversals
遍历的核心逻辑,主要有三个步骤:measure, layout和draw。
如果是第一次调用,所有的子对象还没有attach到窗口上,需要首先dispatchAttachedToWindow。Attach到哪里呢,PhoneWindow的DecorView。
这个方法没有被DecorView重载,直接调用的是ViewGroup的dispatchAttachedToWindow。
### 54. ViewGroup之dispatchAttachedToWindow
根元素被attach到Window上之后,开始递归它的子节点,使每个子节点都attach到父节点上。
执行结束后,通过回调onAttachedToWindow来通知节点已经被attach到Window上了。
在被attach到Window之前,View实际上是没有大小的,因为还不知道被用到哪里呢,无法去做测量。
然后,回到performTraversals中,在执行三大操作之前,先去看看队列里还有什么未执行的任务没有,有的话就先执行之。
getRunQueue().executeActions(mAttachInfo.mHandler);
由于是第一次画,所以mLayoutRequested为true,我们还不知道窗口大小是多大,于是来一次测量,调用measureHierarchy.
windowSizeMayChange |= measureHierarchy(host, lp, res,desiredWindowWidth, desiredWindowHeight);
测量完成之后,就可以开始布局了,调用relayoutWindow.
### 55. ViewRootImpl之relayoutWindow
relayoutWindow当然不是本地能搞得定的,于是通过IPC调,mWindowSession的relayout去通知WmS去干这事儿。
### 56. Session之relayout
IPC调用,调用WmS的relayoutWindow。
### 57. WindowManagerService之relayoutWindow
WmS准备第一次画之前,先来个进场动画吧。
winAnimator.applyEnterAnimationLocked();
然后创建个新的Surface吧。
SurfaceControl surfaceControl = winAnimator.createSurfaceLocked();
最后调用performLayoutAndPlaceSurfacesLocked方法
### 58. WindowManagerService之performLayoutAndPlaceSurfacesLocked
这里边还要走一个最多6次的循环,每次都调用performLayoutAndPlaceSurfacesLockedLoop。
### 59. WindowManagerService之performLayoutAndPlaceSurfacesLockedLoop
调用performLayoutAndPlaceSurfacesLockedInner
### 60. WindowManagerService之performLayoutAndPlaceSurfacesLockedInner
真正执行layout的逻辑。
Measure和layout完成了,最后终于可以画了。回到performTraversals中,调用performDraw。
### 61. ViewRootImpl之performDraw
先调用draw去通知绘制线程开始画。
然后把所有的动画全停掉。
### 62. ViewRootImpl之draw
如果支持硬件加速,就调用HardwareRenderer抽象类的draw方法去画。
### 63. ThreadedRenderer之draw
路径:frameworks/base/core/java/android/view/ThreadedRenderer.java
### 64. ThreadedRenderer之nSyncAndDrawFrame
这是个native方法,真正实现调用GPU去绘制。调用的是android_view_ThreadedRender_syncAndDrawFrame函数。
### 65. android_view_ThreadedRenderer_syncAndDrawFrame函数
路径:frameworks/base/core/jni/android_view_ThreadedRenderer.cpp
再调用RenderProxy的syncAndDrawFrame。
### 66. RenderProxy::syncAndDrawFrame
路径:frameworks/base/libs/hwui/renderthread/RenderProxy.cpp
调用DrawFrameTask的drawFrame函数。
### 67. DrawFrameTask::drawFrame
路径:frameworks/base/libs/hwui/renderthread/DrawFrameTask.cpp
调用postAndWait。
### 68. DrawFrameTask::postAndWait
放到队列里,等着VSYNC信号来了就调用吧。
void DrawFrameTask::postAndWait() {
AutoMutex _lock(mLock);
mRenderThread->queue(this);
mSignal.wait(mLock);
}