Activity启动过程中做了哪些事情?下面的时序图展示里启动过程中函数的调用过程, 从图中可以知道大概流程。

在介绍细节的时候是从上往下函数调用过程介绍的,如果不知道某个函数是在哪里被谁调用的,可以回过头来看下时序图。下面是对一些细节进行介绍。

1. 在Android中有两种操作会引发Activity的启动,一种用户点击Launcher的应用程序图标时,Launcher会为启动应用程序的主Activity。另外一种是在已经起来的Activity内部通过调用startActvity接口启动新的Activity。每一个Activity都可以在内部启动新的Activity。图中就是从一个Activity调用startActivity启动另外一个Activity开始。

startActivity()@Activity.java

  1. public void startActivity(Intent intent, Bundle options) {
  2. if (options != null) {
  3. startActivityForResult(intent, -1, options);
  4. } else {
  5. // Note we want to go through this call for compatibility with
  6. // applications that may have overridden the method.
  7. startActivityForResult(intent, -1);
  8. }
  9. }

startActivity()中调用携带requestCode参数的startActivityForResult()启动新的activity。

startActivityForResult()@Activity.java

  1. public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
  2. //一般的Activity的mParent为null
  3. if (mParent == null) {
  4. //调用Instrumentation.execStartActivity()启动新的Activity。mMainThread类型为ActivityThread, 在attach()函数被回调时被赋值。
  5. Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options);
  6. if (ar != null) { // 如果activity之前已经启动,而且处于阻塞状态,execStartActivity函数直接返回要启动的activity的result或者null。(注意:这就是Activity.onActivityResult()会在启动另外一个activity启动时被回调的原因。
  7. // 若result非空,发送结果给本activity,即onActivityResult会被调用。
  8. mMainThread.sendActivityResult(mToken, mEmbeddedID, requestCode, ar.getResultCode(),
  9. ar.getResultData());
  10. }
  11. if (requestCode >= 0) {
  12. // 如果这次启动需要被启动的activity返回一个结果,则在收到返回结果前,本activity保持不可见。
  13. mStartedActivity = true;
  14. }
  15.  
  16. final View decor = mWindow != null ? mWindow.peekDecorView() : null;
  17. if (decor != null) {
  18. decor.cancelPendingInputEvents();
  19. }
  20. // TODO Consider clearing/flushing other event sources and events for child windows.
  21. } else {
  22. //在ActivityGroup内部的Activity调用startActivity的时候会走到这里,内部处理逻辑和上面是类似的
  23. if (options != null) {
  24. mParent.startActivityFromChild(this, intent, requestCode, options);
  25. } else {
  26. mParent.startActivityFromChild(this, intent, requestCode);
  27. }
  28. }
  29. }

Instrumentation类的功能是辅助Activity的监控和测试,接着看execStartActivity()函数的实现。

execStartActivity()@Instrumentation.java

  1. 1 public ActivityResult execStartActivity(
  2. 2 Context who, IBinder contextThread, IBinder token, Activity target,
  3. 3 Intent intent, int requestCode, Bundle options) {
  4. 4 //将contextThread转成ApplicationThread.
  5. 5 IApplicationThread whoThread = (IApplicationThread) contextThread;
  6. 6 if (mActivityMonitors != null) {
  7. 7 synchronized (mSync) {
  8. 8 //检查是否存在这个activity
  9. 9 final int N = mActivityMonitors.size();
  10. 10 for (int i=0; i<N; i++) {
  11. 11 final ActivityMonitor am = mActivityMonitors.get(i);
  12. 12 if (am.match(who, null, intent)) {
  13. 13 am.mHits++;
  14. 14 if (am.isBlocking()) {                       //若找到,而且处于阻塞状态,直接返回。         
  15. 15 return requestCode >= 0 ? am.getResult() : null;
  16. 16 }
  17. 17 break;
  18. 18 }
  19. 19 }
  20. 20 }
  21. 21 }
  22. 22 try {
  23. 23 intent.migrateExtraStreamToClipData();     //转移数据
  24. 24 intent.prepareToLeaveProcess();            //准备让intent离开一个app进程
  25. 25 //通过AcitivityManagerNative与ActivityManagerService关联起来,两个类的关系如下图,由ActivityManagerService去执行实际动作。
  26. 26 int result = ActivityManagerNative.getDefault()
  27. 27 .startActivity(whoThread, who.getBasePackageName(), intent,
  28. 28 intent.resolveTypeIfNeeded(who.getContentResolver()),
  29. 29 token, target != null ? target.mEmbeddedID : null,
  30. 30 requestCode, 0, null, null, options);
  31. 31 //检查启动结果,如果无法打开activity,则抛出诸如ActivityNotFoundException类似的各种异常
  32. 32 checkStartActivityResult(result, intent);
  33. 33 } catch (RemoteException e) {
  34. 34 }
  35. 35 return null;
  36. 36 }

2. ActivityManager的功能是与系统中所有运行着的Activity交互提供了接口,主要的接口围绕着运行中的进程信息,任务信息,服务信息等,它的大多数功能都是调用了ActivityManagerNative类接口来完成的。
ActivityManager相关静态类图如下图,可以看出这是典型的Proxy模式:

结合面的类结构图,其中ActivityManager是一个客户端,为了减少它与ActivityManagerService的耦合度,在这中间使用了ActivityManagerNative类,该类内部使用ActivityManagerProxy代理类,所有对 ActivityManagerService的访问都转换成对代理类的访问,这样ActivityManager就与ActivityManagerService解耦了。
    为了让代理类与被代理类保持一致的接口,由IActivityManager作为ActivityManagerProxy和ActivityManagerNative的公共接口,ActivityManagerService继承于ActivityManagerNative,也具有相同的接口。

图中绿色的部分是在SDK中开放给应用程序开发人员的接口,蓝色的部分是Proxy模式的实现,红色的部分是底层的服务实现,是真正的动作执行者。

3. startActivity()@ActivityManagerService.java

  1. @Override
  2. public final int startActivity(IApplicationThread caller, String callingPackage,
  3. Intent intent, String resolvedType, IBinder resultTo,
  4. String resultWho, int requestCode, int startFlags,
  5. String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
  6. return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
  7. resultWho, requestCode, startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
  8. }
  9.  
  10. @Override
  11. public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
  12. Intent intent, String resolvedType, IBinder resultTo,
  13. String resultWho, int requestCode, int startFlags,
  14. String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
  15. enforceNotIsolatedCaller("startActivity");
  16. userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
  17. false, true, "startActivity", null);
  18. // TODO: Switch to user app stacks here.
  19. return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
  20. resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
  21. null, null, options, userId);
  22. }

类ActivityStackSupervisor是用来辅助ActivityManagerService对Activity和Task的管理的。其中用ActivityStackSupervisor类型来进行对Task的操作,用ActivityStack对Acitivity进行操作。

4. 调用mStackSupervisor.startActivityMayWait()函数后,会执行下面几个函数,调用关系参照时序图,函数里涉及很多细节,这里只简单描述下它们的主要功能:

调用9. ActivityStackSupervisor.startActivityLocked():  检查启动权限,创建新的ActivityRecord。

调用10. ActivityStackSupervisor.startActivityUncheckedLocked():处理intent携带的launch flags, launchMode。(后面再研究launch相关的flag和mode)

调用11. ActivityStack.startActivityLocked():将activity放到所属task的顶部,重置Task(resetTaskIfNeededLocked),调用WindowManager.setAppStartingWindow()。

调用13. ActivityStackSupervisor.resumeTopActivitiesLocked():判断ActivityStack数组中是否存在target ActivityStack。

调用14. ActivityStack.resumeTopActivityLocked(): 从当前activity切换到要启动的activity。

调用15. ActivityStackSupervisor.startSpecificActivityLocked():获取ProcessRecord(若要启动的activity的应用已经在运行),若获取ProcessRecord存在则调用realStartActivityLocked(),否则调用 ActivityManagerServices.startProcessLocked()创建新的ProcessRecord,最后调用Process.start()启动新的进程(最终调用Zygote启动新的进程,为了避免混淆,这部分在时序图中没有体现,后面再研究)。

调用16. ActivityStackSupervisor.realStartActivityLocked(): 调用mWindowManager.setAppVisibility()设置app可见。

调用19. ActivityThread.scheduleLauncherActivity(): 发送Message LAUNCH_ACTIVITY给Handler.

5. Handler接收到message后,执行ActivityThread.handleLaunchActivity()。

handleLaunchActivity()@ActivityThread.java

  1. private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  2. ......
  3. Activity a = performLaunchActivity(r, customIntent); // 返回一个activity.
  4. if (a != null) {
  5. r.createdConfig = new Configuration(mConfiguration);
  6. Bundle oldState = r.state;
  7. handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed);
  8.  
  9. if (!r.activity.mFinished && r.startsNotResumed) {
  10. // 当这个activity没有finished而且没有处于resumed状态时,Acivity Manager实际上想要这个activity以paused状态开始,因为它需要可见,但是又不在前台。
                // 为此,需要经过正常启动(因为activity希望在它们的window被显示前,它们第一次运行时通过onResume),然后暂停它。The activity manager actually wants this one to start out
  11. //然而,在这种情况下,不需要走完整的暂停周期(比如freezing等),因为activity假定它可以刚好保留它当前的所有状态。
  12. try {
  13. r.activity.mCalled = false;
  14. mInstrumentation.callActivityOnPause(r.activity);
  15.                ......
  16. } catch (SuperNotCalledException e) {
  17. ......
  18. } catch (Exception e) {
  19. ......
  20. }
  21. r.paused = true;
  22. }
  23. } else {
  24. ......
  25. }
  26. }

6.进一步看performLaunchActivity(),这个函数做了几件重要的事情:创建activity实例,调用Activity.attach()设置参数,触发Activity.onCreate()。

performLaunchActivity()@ActivityThread.java

  1. private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  2.  
  3. ActivityInfo aInfo = r.activityInfo;
  4. if (r.packageInfo == null) { // 填充package info
  5. r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
  6. Context.CONTEXT_INCLUDE_CODE);
  7. }
  8.  
  9. ComponentName component = r.intent.getComponent();
  10. if (component == null) {
  11. component = r.intent.resolveActivity(mInitialApplication.getPackageManager());
  12. r.intent.setComponent(component); //设置Component
  13. }
  14. if (r.activityInfo.targetActivity != null) {
  15. component = new ComponentName(r.activityInfo.packageName,
  16. r.activityInfo.targetActivity);
  17. }
  18.  
  19. Activity activity = null;
  20. try {
  21. java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
  22. activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent); // 根据Activity的类名,通过Java反射机制创建对应的Activity.
  23. StrictMode.incrementExpectedActivityCount(activity.getClass());
  24. r.intent.setExtrasClassLoader(cl);
  25. if (r.state != null) {
  26. r.state.setClassLoader(cl);
  27. }
  28. } catch (Exception e) {
  29. ......
  30. }
  31.  
  32. try {
  33. Application app = r.packageInfo.makeApplication(false, mInstrumentation);
  34.  
  35. if (activity != null) {
  36. Context appContext = createBaseContextForActivity(r, activity); // Activity中getContext()函数返回的就是这个对象。
  37. CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
  38. Configuration config = new Configuration(mCompatConfiguration);
  39. ......
  40. // 将Context,ActivityThread,Instrumentation,Application等设置给新建的Activity,供activity使用。
  41. activity.attach(appContext, this, getInstrumentation(), r.token,
  42. r.ident, app, r.intent, r.activityInfo, title, r.parent,
  43. r.embeddedID, r.lastNonConfigurationInstances, config);
  44.  
  45. if (customIntent != null) {
  46. activity.mIntent = customIntent;
  47. }
  48. r.lastNonConfigurationInstances = null;
  49. activity.mStartedActivity = false;
  50. int theme = r.activityInfo.getThemeResource();
  51. if (theme != 0) {
  52. activity.setTheme(theme);                                             // 设置theme
  53. }
  54.  
  55. activity.mCalled = false;
  56. mInstrumentation.callActivityOnCreate(activity, r.state); // 这个函数会使Activity的onCreate()函数被调用
  57. if (!activity.mCalled) {
  58. throw new SuperNotCalledException(
  59. "Activity " + r.intent.getComponent().toShortString() +
  60. " did not call through to super.onCreate()");
  61. }
  62. r.activity = activity;
  63. r.stopped = true;
  64. if (!r.activity.mFinished) {
  65. activity.performStart();                                            // 这个函数会使Activity的onStart()函数被调用
  66. r.stopped = false;
  67. }
  68. if (!r.activity.mFinished) {
  69. if (r.state != null) {
  70. mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
  71. }
  72. }
  73. if (!r.activity.mFinished) {
  74. activity.mCalled = false;
  75. mInstrumentation.callActivityOnPostCreate(activity, r.state);
  76. if (!activity.mCalled) {
  77. throw new SuperNotCalledException(
  78. "Activity " + r.intent.getComponent().toShortString() +
  79. " did not call through to super.onPostCreate()");
  80. }
  81. }
  82. }
  83. r.paused = true;
  84. mActivities.put(r.token, r);
  85. } catch (SuperNotCalledException e) {
  86. ......
  87. } catch (Exception e) {
  88. ......
  89. }
  90. return activity;
  91. }

7.下面分析下Activity.attach()函数,它创建window对象,设置window manager。

attach()@Activity.java

  1. final void attach(Context context, ActivityThread aThread,
  2. Instrumentation instr, IBinder token, int ident,
  3. Application application, Intent intent, ActivityInfo info,
  4. CharSequence title, Activity parent, String id,
  5. NonConfigurationInstances lastNonConfigurationInstances,
  6. Configuration config) {
  7. attachBaseContext(context); // 把context赋值给父类的mBase成员
  8.  
  9. mFragments.attachActivity(this, mContainer, null);
  10.  
  11. mWindow = PolicyManager.makeNewWindow(this); // 调用PolicyManager的函数创建Window对象。
  12. mWindow.setCallback(this);
  13. mWindow.getLayoutInflater().setPrivateFactory(this);
  14. if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
  15. mWindow.setSoftInputMode(info.softInputMode); //设置输入法mode
  16. }
  17. if (info.uiOptions != 0) {
  18. mWindow.setUiOptions(info.uiOptions);
  19. }
  20. mUiThread = Thread.currentThread();
  21. // 赋值给Acitivity的各个成员
  22. mMainThread = aThread; //mMainThread实际上为ActivityThread。
  23. mInstrumentation = instr;
  24. mToken = token;
  25. mIdent = ident;
  26. mApplication = application;
  27. mIntent = intent;
  28. mComponent = intent.getComponent();
  29. mActivityInfo = info;
  30. mTitle = title;
  31. mParent = parent;
  32. mEmbeddedID = id;
  33. mLastNonConfigurationInstances = lastNonConfigurationInstances;
  34.  
  35. // 创建WindowManager对象并设置给window,供window使用.
  36. mWindow.setWindowManager((WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
  37. mToken, mComponent.flattenToString(),
  38. (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
  39. if (mParent != null) {
  40. mWindow.setContainer(mParent.getWindow());
  41. }
  42. mWindowManager = mWindow.getWindowManager();   // 保存WindowManager对象.
  43. mCurrentConfig = config;
  44. }

8. 其中一个关键的函数PolicyManager.makeNewWindow()返回的Window对象,实际上是一个PhoneWindow对象。

具体创建过程参考下面代码:

class PolicyManager@PolicyManager.java

  1. public final class PolicyManager {
  2. private static final String POLICY_IMPL_CLASS_NAME =
  3. "com.android.internal.policy.impl.Policy";
  4.  
  5. private static final IPolicy sPolicy; // sPolicy为单例的IPolicy对象。
  6. static {
  7. // Pull in the actual implementation of the policy at run-time
  8. try {
  9. Class policyClass = Class.forName(POLICY_IMPL_CLASS_NAME);
  10. sPolicy = (IPolicy)policyClass.newInstance(); // 创建Policy对象。
  11. } catch (ClassNotFoundException ex) {
  12. ......
  13. }
  14. }
  15. // Cannot instantiate this class
  16. private PolicyManager() {}
  17.  
  18. // The static methods to spawn new policy-specific objects
  19. public static Window makeNewWindow(Context context) {
  20. return sPolicy.makeNewWindow(context); //通过Policy对象的makeNewWindow创建一个Window。
  21. }
  22. ......
  23. }

class Policy@Policy.java

  1. public class Policy implements IPolicy {
  2. private static final String TAG = "PhonePolicy";
  3.  
  4. private static final String[] preload_classes = {
  5. "com.android.internal.policy.impl.PhoneLayoutInflater",
  6. "com.android.internal.policy.impl.PhoneWindow",
  7. "com.android.internal.policy.impl.PhoneWindow$1",
  8. "com.android.internal.policy.impl.PhoneWindow$DialogMenuCallback",
  9. "com.android.internal.policy.impl.PhoneWindow$DecorView",
  10. "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState",
  11. "com.android.internal.policy.impl.PhoneWindow$PanelFeatureState$SavedState",
  12. };
  13.  
  14. static {
  15. // For performance reasons, preload some policy specific classes when
  16. // the policy gets loaded.
  17. for (String s : preload_classes) { // 加载所有的类
  18. try {
  19. Class.forName(s);
  20. } catch (ClassNotFoundException ex) {
  21. ......
  22. }
  23. }
  24. }
  25. public Window makeNewWindow(Context context) {
  26. return new PhoneWindow(context); // 实际返回的PhoneWindow对象。
  27. }
  28. ......
  29. }

9setWindowManager()@Window.java

  1. public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
  2. boolean hardwareAccelerated) {
  3. mAppToken = appToken;
  4. mAppName = appName;
  5. mHardwareAccelerated = hardwareAccelerated || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);
  6. if (wm == null) {
  7. wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
  8. }
  9. mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);             // 创建一个WindowManagerImpl对象
  10. }

到这里可以看到,Activity成员变量mWindow实际上是PhoneWindow类型, 变量mWindowManager实际上是WindowManagerImpl。这

10Acitivity.attach()函数被调用之后,performLaunchActivity还会触发Activity.onCreate()函数被调用,在这个函数中会调用setContentView()函数设置Activity的UI内容。

setContentView()有三种实现,它们的功能基本一致,都是将view添加到mContentParent中:

setContentView()@Activity.java

  1. // 通过一个布局资源设置activity的内容。
  2. public void setContentView(int layoutResID) {
  3. getWindow().setContentView(layoutResID);
  4. initActionBar();
  5. }
  6.  
  7. // 直接将View作为内容直接设置到activity的视图层次中。这种方式设置给view的layoutparams将不起作用,默认为MATCH_PARENT.
  8. public void setContentView(View view) {
  9. getWindow().setContentView(view);
  10. initActionBar();
  11. }
  12.  
  13. // 设置activity的内容为view, 并设置view的LayoutParams.
  14. public void setContentView(View view, ViewGroup.LayoutParams params) {
  15. getWindow().setContentView(view, params);
  16. initActionBar();
  17. }

下面给出其中一种实现:

setContentView()@PhoneWindow.java

  1. public void setContentView(View view, ViewGroup.LayoutParams params) {
  2. if (mContentParent == null) {
  3. installDecor();                // 初始化DecorView和mContentParent.
  4. } else {
  5. mContentParent.removeAllViews();
  6. }
  7. mContentParent.addView(view, params);
  8. final Callback cb = getCallback();
  9. if (cb != null && !isDestroyed()) {
  10. cb.onContentChanged();
  11. }
  12. }

installDecor()@PhoneWindow.java

  1. private void installDecor() {
  2. if (mDecor == null) {
  3. mDecor = generateDecor();
  4. ......
  5. }
  6. if (mContentParent == null) {
  7. mContentParent = generateLayout(mDecor);
  8. mTitleView = (TextView)findViewById(com.android.internal.R.id.title); // 创建标题栏
  9. ......
  10. }
  11. }

generateDecor()@PhoneWindow.java

  1. protected DecorView generateDecor() {
  2. return new DecorView(getContext(), -1); // DecorView从FrameLayout派生,同时实现RootViewSurfaceTaker接口。
  3. }

generateLayout()@PhoneWindow.java

  1. protected ViewGroup generateLayout(DecorView decor) {
  2. ......
  3. // Inflate the window decor.
  4. int layoutResource; // 根据情况获取相应的标题栏资源ID。
  5. int features = getLocalFeatures();
  6. if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
  7. if (mIsFloating) {
  8. ......
  9. layoutResource = res.resourceId;
  10. }
  11. ......
  12. }
  13.  
  14. mDecor.startChanging();
  15.  
  16. View in = mLayoutInflater.inflate(layoutResource, null);        //inflate 标题栏
  17. decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); // 加入标题栏
  18.  
  19. ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT); // ID_ANDROID_CONTENT:xml布局文件中main layout的ID, 实际上是mDecorView的一部分。
  20. ......
  21. mDecor.finishChanging();
  22. return contentParent;
  23. }

findViewById()@Window.java

  1. public View findViewById(int id) {
  2. return getDecorView().findViewById(id);
  3. }

通过上面的代码可以看到,在Activity.onCreate()函数里调用setContentView设置的View,实际上会作为DecorView的子view。DecorView还处理了标题栏显示等工作。

addView()@ViewGroup.java

  1. public void addView(View child, int index, LayoutParams params) {
  2. // addViewInner()函数中设置LayoutParams时会调用child.requestLayout(),在这里调用,为了在这里阻塞child的request.
  3. requestLayout();
  4. invalidate(true); //在下一篇文章中会介绍这个函数
  5. addViewInner(child, index, params, false);
  6. }

11我们接着看handleLaunchActivity()中的handleResumeActivity()函数,

handleResumeActivity()@ActivityThread.java

  1. final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) {
  2. ......
  3. ActivityClientRecord r = performResumeActivity(token, clearHide); //会调用到Activity.onResume().
  4.  
  5. if (r != null) {
  6. final Activity a = r.activity;
  7. final int forwardBit = isForward ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
  8.  
  9. // If the window hasn't yet been added to the window manager,
  10. // and this guy didn't finish itself or start another activity,
  11. // then go ahead and add the window.
  12. // 若这个activity的window没有加到window manager中,而且它没有自己finish或者启动另外一个acitivity,那就继续,添加这个window.
  13. boolean willBeVisible = !a.mStartedActivity;
  14. if (!willBeVisible) {
  15. try {
  16. willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(a.getActivityToken());
  17. } catch (RemoteException e) {
  18. }
  19. }
  20. if (r.window == null && !a.mFinished && willBeVisible) {
  21. r.window = r.activity.getWindow(); // 获得在attach()函数中创建出来的window对象。
  22. View decor = r.window.getDecorView(); // 获得一个View对象
  23. decor.setVisibility(View.INVISIBLE);
  24. ViewManager wm = a.getWindowManager(); // 获得ViewManager对象
  25. WindowManager.LayoutParams l = r.window.getAttributes();
  26. a.mDecor = decor;
  27. l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
  28. l.softInputMode |= forwardBit;
  29. if (a.mVisibleFromClient) {
  30. a.mWindowAdded = true;
  31. wm.addView(decor, l); // 添加View对象到WindowManager中。
  32. }
  33. } else if (!willBeVisible) { // 如果window已经被添加了,但在resume时启动另外的activity,这个window将隐藏。
  34. r.hideForNow = true;
  35. }
  36.  
  37. // Get rid of anything left hanging around.
  38. cleanUpPendingRemoveWindows(r);
  39. // 如果window添加了,执行到这的时候就可见了。
  40. if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
  41. if (r.newConfig != null) {
  42. performConfigurationChanged(r.activity, r.newConfig);
  43. freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
  44. r.newConfig = null;
  45. }
  46. WindowManager.LayoutParams l = r.window.getAttributes();
  47. if ((l.softInputMode & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) != forwardBit) {
  48. l.softInputMode = (l.softInputMode
  49. & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
  50. | forwardBit;
  51. if (r.activity.mVisibleFromClient) {
  52. ViewManager wm = a.getWindowManager();
  53. View decor = r.window.getDecorView();
  54. wm.updateViewLayout(decor, l); // 根据输入法显示模式调整winddow layout。
  55. }
  56. }
  57. r.activity.mVisibleFromServer = true;
  58. mNumVisibleActivities++;
  59. if (r.activity.mVisibleFromClient) {
  60. r.activity.makeVisible();
  61. }
  62. }
  63.  
  64. if (!r.onlyLocalRequest) {
  65. r.nextIdle = mNewActivities;
  66. mNewActivities = r;
  67. Looper.myQueue().addIdleHandler(new Idler());
  68. }
  69. r.onlyLocalRequest = false;
  70.  
  71. // Tell the activity manager we have resumed.
  72. if (reallyResume) {
  73. try {
  74. ActivityManagerNative.getDefault().activityResumed(token);
  75. } catch (RemoteException ex) {
  76. }
  77. }
  78. } else {
  79. // If an exception was thrown when trying to resume, then just end this activity.
  80. // 如果resume过程出现异常,就finish这个activity.
  81. try {
  82. ActivityManagerNative.getDefault().finishActivity(token, Activity.RESULT_CANCELED, null);
  83. } catch (RemoteException ex) {
  84. }
  85. }
  86. }

addView()@WindowManagerGlobal.java

  1. public void addView(View view, ViewGroup.LayoutParams params,
  2. Display display, Window parentWindow) {
  3. ......
  4. ViewRootImpl root;
  5. View panelParentView = null;
  6.  
  7. synchronized (mLock) {
  8. ......
  9. root = new ViewRootImpl(view.getContext(), display);    // 创建ViewRootImpl对象
  10.  
  11. view.setLayoutParams(wparams);
  12.  
  13. mViews.add(view);
  14. mRoots.add(root);
  15. mParams.add(wparams);
  16. }
  17. // do this last because it fires off messages to start doing things
  18. try {
  19. root.setView(view, wparams, panelParentView);          // setView()内调用requestLayout(). 在被加到WindowManager之前调度第一次layout,确保收到系统事件之前重新进行了布局。
  20. } catch (RuntimeException e) {
  21. ......
  22. }
  23. }

ViewRootImpl及setView()涉及到了UI绘制。启动相关更多的细节在下一篇中进行分析。

Activity启动流程的更多相关文章

  1. Cocos2d-x3.3RC0的Android编译Activity启动流程分析

    本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2 ...

  2. 2018-01-13 view绘制流程-activity启动流程-window-decorView-ViewRootImpl关系

    1.activity启动流程: https://www.jianshu.com/p/927ca995bca6 http://blog.csdn.net/qian520ao/article/detail ...

  3. 《转》深入理解Activity启动流程(四)–Activity Task的调度算法

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  4. 《转》深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  5. 《转》深入理解Activity启动流程(三)–Activity启动的详细流程1

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启 ...

  6. 《转》深入理解Activity启动流程(二)–Activity启动相关类的类图

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先为大家介绍Act ...

  7. 《转》深入理解Activity启动流程(一)–Activity启动的概要流程

    本文原创作者:Cloud Chou. 原文地址:http://www.cloudchou.com/android/post-788.html Android中启动某个Activity,将先启动Acti ...

  8. 深入理解Activity启动流程(四)–Activity Task的调度算法

    本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--Activity启动的概要流程 深入理解Activity启动流程(二)- ...

  9. 深入理解Activity启动流程(三)–Activity启动的详细流程2

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 深入理解Activity启动流程(一)--A ...

  10. 深入理解Activity启动流程(二)–Activity启动相关类的类图

    本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先 ...

随机推荐

  1. node升级更新最近稳定版

    今天,又发现一个超级简单的升级Node.js的方法.一行命令搞定,省去了重新编译安装的过程. node有一个模块叫n(这名字可够短的...),是专门用来管理node.js的版本的. 首先安装n模块: ...

  2. 08-SSH综合案例:前台用户模块:注册页面的前台JS校验

    这个是MyEclipse设置的问题 把设置去掉就没问题了. 你也可以在每一个input后面加个span来显示提示的信息.这些东西也要提交到后台,后台也是要对这些东西进行校验的.

  3. 54. Spiral Matrix (Graph)

    Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral or ...

  4. spring boot 1

    1.创建项目. meven可以配置阿里云meven镜像 <mirror> <id>nexus-aliyun</id> <mirrorOf>central ...

  5. NOSQL之Redis、MongDB、Habase、Cassandra的介绍与比较

    一.Redis介绍     1.1Redis优点 (1)Redis拥有非常丰富的数据结构: (2)Redis提供事务的功能,可以保证一串命令的原子性,中间不会被任何打断. (3)数据存储在内存中,读写 ...

  6. SLAM拾萃(2):doxygen

    今天给大家介绍一下doxygen.这个工具由来已久了,至少08年左右就已经在用了,但是目前还没见到好的介绍.我个人觉得这是个很简单易用的工具,但是为什么看了别人介绍反而觉得复杂了……所以趁着今天比较闲 ...

  7. Object 和 JSON 区别联系

    JavaScript Object-based JavaScript is almost entirely object-based. Object name Object property name ...

  8. Zend_Controller_Front 研究

    如果你裸写php,一个项目就会出现很多的页面控制器(Page Controller),如果项目很大,重复代码就很多,越来越变得很难维护.有了问题,自然就有解决方案!于是前端设计模式  闪亮登场! 前端 ...

  9. SQL描述(2)

    很久之前就想写出来,就是因为自己太懒,憋了怎么久.本文关于使用ORACLE分析函数对一些经济指标进行计算.表indi_value有3个关键的字段:indi_date,indi_value,indi_i ...

  10. linux squid

    iptables -F iptables -F -t nat 网关 iptables -t nat -A POSTROUTING -s 10.1.0.0/16 -o eth0 -j MASQUERAD ...