【Android源码 栏目提醒】:网学会员在Android源码 频道为大家收集整理了“Android应用程序启动过程源代码分析 - 电子设计“提供大家参考,希望对大家有所帮助!
Android应用程序启动过程源代码分析 前文简要介绍了
Android应用程序的Activity的启动过程。
在
Android系统中应用程序是由Activity组成的因此应用程序的启动过程实际上就是应用程序中的默认Activity的启动过程本文将详细分析应用程序框架层的源代码了解
Android应用程序的启动过程。
在上一篇文章
Android应用程序的Activity启动过程简要介绍和学习计划中我们举例子说明了启动
Android应用程序中的Activity的两种情景其中在手机屏幕中点击应用程序图标的情景就会引发
Android应用程序中的默认Activity的启动从而把应用程序启动起来。
这种启动方式的特点是会启动一个新的进程来加载相应的Activity。
这里我们继续以这个例子为例来说明
Android应用程序的启动过程即MainActivity的启动过程。
MainActivity的启动过程如下图所示 点击查看大图 下面详细分析每一步是如何实现的。
Step 1. Launcher.startActivitySafely 在
Android系统中应用程序是由Launcher启动起来的其实Launcher本身也是一个应用程序其它的应用程序安装后就会Launcher的界面上出现一个相应的图标点击这个图标时Launcher就会对应的应用程序启动起来。
Launcher的源代码工程在packages/apps/Launcher2目录下负责启动其它应用程序的源代码实现在src/com/
android/launcher2/Launcher.java文件中 java view plaincopy 1. / 2. Default launcher application. 3. / 4. public final class Launcher extends Activity 5. implements View.OnClickListener OnLongClickListener LauncherModel.Callbacks AllAppsView.Watcher 6. 7. ...... 8. 9. / 10. Launches the intent referred by the clicked shortcut. 11. 12. param v The view representing the clicked shortcut. 13. / 14. public void onClickView v 15. Object tag v.getTag 16. if tag instanceof ShortcutInfo 17. // Open shortcut 18. final Intent intent ShortcutInfo tag.intent 19. int pos new int2 20. v.getLocationOnScreenpos 21. intent.setSourceBoundsnew Rectpos0 pos1 22. pos0 v.getWidth pos1 v.getHeight 23. startActivitySafelyintent tag 24. else if tag instanceof FolderInfo 25. ...... 26. else if v mHandleView 27. ...... 28. 29. 30. 31. void startActivitySafelyIntent intent Object tag 32. intent.addFlagsIntent.FLAG_ACTIVITY_NEW_TASK 33. try 34. startActivityintent 35. catch ActivityNotFoundException e 36. ...... 37. catch SecurityException e 38. ...... 39. 40. 41. 42. ...... 43. 44. 回忆一下前面一篇文章
Android应用程序的Activity启动过程简要介绍和学习计划说到的应用程序Activity它的默认Activity是MainActivity这里是AndroidManifest.xml文件中配置的 html view plaincopy 1. ltactivity
android:namequot.MainActivityquot 2.
android:labelquotstring/app_namequotgt 3. ltintent-filtergt 4. ltaction
android:namequotandroid.intent.action.MAINquot /gt 5. ltcategory
android:namequotandroid.intent.category.LAUNCHERquot /gt 6. lt/intent-filtergt 7. lt/activitygt 因此这里的intent包含的信息为action quotandroid.intent.action.Mainquotcategoryquotandroid.intent.category.LAUNCHERquot cmpquotshy.luo.activity/.MainActivityquot表示它要启动的Activity为shy.luo.activity.MainActivity。
Intent.FLAG_ACTIVITY_NEW_TASK表示要在一个新的Task中启动这个Activity注意Task是
Android系统中的概念它不同于进程Process的概念。
简单地说一个Task是一系列Activity的集合这个集合是以堆栈的形式来组织的遵循后进先出的原则。
事实上Task是一个非常复杂的概念有兴趣的读者可以到官网http://developer.
android.com/guide/topics/manifest/activity-element.html查看相关的资料。
这里我们只要知道这个MainActivity要在一个新的Task中启动就可以了。
Step 2. Activity.startActivity 在Step 1中我们看到Launcher继承于Activity类而Activity类实现了startActivity函数因此这里就调用了Activity.startActivity函数它实现在frameworks/base/core/java/
android/app/Activity.java文件中 java view plaincopy 1. public class Activity extends ContextThemeWrapper 2. implements LayoutInflater.Factory 3. Window.Callback KeyEvent.Callback 4. OnCreateContextMenuListener ComponentCallbacks 5. 6. ...... 7. 8. Override 9. public void startActivityIntent intent 10. startActivityForResultintent -1 11. 12. 13. ...... 14. 15. 这个函数实现很简单它调用startActivityForResult来进一步处理第二个参数传入-1表示不需要这个Actvity结束后的返回结果。
Step 3. Activity.startActivityForResult 这个函数也是实现在frameworks/base/core/java/
android/app/Activity.java文件中 java view plaincopy 1. public class Activity extends ContextThemeWrapper 2. implements LayoutInflater.Factory 3. Window.Callback KeyEvent.Callback 4. OnCreateContextMenuListener ComponentCallbacks 5. 6. ...... 7. 8. public void startActivityForResultIntent intent int requestCode 9. if mParent null 10. Instrumentation.ActivityResult ar 11. mInstrumentation.execStartActivity 12. this mMainThread.getApplicationThread mToken this 13. intent requestCode 14. ...... 15. else 16. ...... 17. 18. 19. 20. ...... 21. 22. 这里的mInstrumentation是Activity类的成员变量它的类型是Intrumentation定义在frameworks/base/core/java/
android/app/Instrumentation.java文件中它用来监控应用程序和系统的交互。
这里的mMainThread也是Activity类的成员变量它的类型是ActivityThread它代表的是应用程序的主线程我们在
Android系统在新进程中启动自定义服务过程startService的原理分析一文中已经介绍过了。
这里通过mMainThread.getApplicationThread获得它里面的ApplicationThread成员变量它是一个Binder对象后面我们会看到ActivityManagerService会使用它来和ActivityThread来进行进程间通信。
这里我们需注意的是这里的mMainThread代表的是Launcher应用程序运行的进程。
这里的mToken也是Activity类的成员变量它是一个Binder对象的远程接口。
Step 4. Instrumentation.execStartActivity 这个函数定义在frameworks/base/core/java/
android/app/Instrumentation.java文件中 java view plaincopy 1. public class Instrumentation 2. 3. ...... 4. 5. public ActivityResult execStartActivity 6. Context who IBinder contextThread IBinder token Activity target 7. Intent intent int requestCode 8. IApplicationThread whoThread IApplicationThread contextThread 9. if mActivityMonitors null 10. ...... 11. 12. try 13. int result ActivityManagerNative.getDefault 14. .startActivitywhoThread intent 15. intent.resolveTypeIfNeededwho.getContentResolver 16. null 0 token target null target.mEmbeddedID : null 17. requestCode false false 18. ...... 19. catch RemoteException e 20. 21. return null 22. 23. 24. ...... 25. 26. 这里的ActivityManagerNative.getDefault返回ActivityManagerService的远程接口即ActivityManagerProxy接口具体可以参考
Android系统在新进程中启动自定义服务过程startService的原理分析一文。
这里的intent.resolveTypeIfNeeded返回这个intent的MIME类型在这个例子中没有AndroidManifest.xml设置MainActivity的MIME类型因此这里返回null。
这里的target不为null但是target.mEmbddedID为null我们不用关注。
Step 5. ActivityManagerProxy.startActivity 这个函数定义在frameworks/base/core/java/
android/app/ActivityManagerNative.java文件中 java view plaincopy 1. class ActivityManagerProxy implements IActivityManager 2. 3. 4. ...... 5. 6. public int startActivityIApplicationThread caller Intent intent 7. String resolvedType Uri grantedUriPermissions int grantedMode 8. IBinder resultTo String resultWho 9. int requestCode boolean onlyIfNeeded 10. boolean debug throws RemoteException 11. Parcel data Parcel.obtain 12. Parcel reply Parcel.obtain 13. data.writeInterfaceTokenIActivityManager.descriptor 14. data.writeStrongBindercaller null caller.asBinder : null 15. intent.writeToParceldata 0 16. data.writeStringresolvedType 17. data.writeTypedArraygrantedUriPermissions 0 18. data.writeIntgrantedMode 19. data.writeStrongBinderresultTo 20. data.writeStringresultWho 21. data.writeIntrequestCode 22. data.writeIntonlyIfNeeded 1 : 0 23. data.writeIntdebug 1 : 0 24. mRemote.transactSTART_ACTIVITY_TRANSACTION data reply 0 25. reply.readException 26. int result reply.readInt 27. reply.recycle 28. data.recycle 29. return result 30. 31. 32. ...... 33. 34. 这里的参数比较多我们先整理一下。
从上面的调用可以知道这里的参数resolvedType、grantedUriPermissions和resultWho均为null参数caller为ApplicationThread类型的Binder实体参数resultTo为一个Binder实体的远程接口我们先不关注它参数grantedMode为0我们也先不关注它参数requestCode为-1参数onlyIfNeeded和debug均空false。
Step 6. ActivityManagerService.startActivity 上一步Step 5通过Binder驱动程序就进入到ActivityManagerService的startActivity函数来了它定义在frameworks/base/services/java/com/
android/server/am/ActivityManagerService.java文件中 java view plaincopy 1. public final class ActivityManagerService extends ActivityManagerNative 2. implements Watchdog.Monitor BatteryStatsImpl.BatteryCallback 3. 4. ...... 5. 6. public final int startActivityIApplicationThread caller 7. Intent intent String resolvedType Uri grantedUriPermissions 8. int grantedMode IBinder resultTo 9. String resultWho int requestCode boolean onlyIfNeeded 10. boolean debug 11. return mMainStack.startActivityMayWaitcaller intent resolvedType 12. grantedUriPermissions grantedMode resultTo resultWho 13. requestCode onlyIfNeeded debug null null 14. 15. 16. 17. ...... 18. 19. 这里只是简单地将操作转发给成员变量mMainStack的startActivityMayWait函数这里的mMainStack的类型为ActivityStack。
Step 7. ActivityStack.startActivityMayWait 这个函数定义在frameworks/base/services/java/com/
android/server/am/ActivityStack.java文件中 java view plaincopy 1. public class ActivityStack 2. 3. ...... 4. 5. final int startActivityMayWaitIApplicationThread caller 6. Intent intent String resolvedType Uri grantedUriPermissions 7. int grantedMode IBinder resultTo 8. String resultWho int requestCode boolean onlyIfNeeded 9. boolean debug WaitResult outResult Configuration config 10. 11. ...... 12. 13. boolean componentSpecified intent.getComponent null 14. 15. // Dont modify the clients object 16. intent new Intentintent 17. 18. // Collect information about the target of the Intent. 19. ActivityInfo aInfo 20. try 21. ResolveInfo rInfo 22. AppGlobals.getPackageManager.resolveIntent 23. intent resolvedType 24. PackageManager.MATCH_DEFAULT_ONLY 25. ActivityManagerService.STOCK_PM_FLAGS 26. aInfo rInfo null rInfo.activityInfo : null 27. catch RemoteException e 28. ...... 29. 30. 31. if aInfo null 32. // Store the found target back into the intent because now that 33. // we have it we never want to do this again. For example if the 34. // user navigates back to this point in the history we should 35. // always restart the exact same activity. 36. intent.setComponentnew ComponentName 37. aInfo.applicationInfo.packageName aInfo.name 38. ...... 39. 40. 41. synchronized mService 42. int callingPid 43. int callingUid 44. if caller null 45. ...... 46. else 47. callingPid callingUid -1 48. 49. 50. mConfigWillChange config null 51. ampamp mService.mConfiguration.diffconfig 0 52. 53. ...... 54. 55. if mMainStack ampamp aInfo null ampamp 56. aInfo.applicationInfo.flagsampApplicationInfo.FLAG_CANT_SAVE_STATE 0 57. 58. ...... 59. 60. 61. 62. int res startActivityLockedcaller intent resolvedType 63. grantedUriPermissions grantedMode aInfo 64. resultTo resultWho requestCode callingPid callingUid 65. onlyIfNeeded componentSpecified 66. 67. if mConfigWillChange ampamp mMainStack 68. ...... 69. 70. 71. ...... 72. 73. if outResult null 74. ...... 75. 76. 77. return res 78. 79. 80. 81. 82. ...... 83. 84. 注意从Step 6传下来的参数outResult和config均为null此外表达式aInfo.applicationInfo.flagsampApplicationInfo.FLAG_CANT_SAVE_STATE 0为false因此这里忽略了无关代码。
下面语句对参数intent的内容进行解析得到MainActivity的相关信息保存在aInfo变量中 java view plaincopy 1. ActivityInfo aInfo 2. try 3. ResolveInfo rInfo 4. AppGlobals.getPackageManager.resolveIntent 5. intent resolvedType 6. PackageManager.MATCH_DEFAULT_ONLY 7. ActivityManagerService.STOCK_PM_FLAGS 8. aInfo rInfo null rInfo.activityInfo : null 9. catch RemoteException e 10. ...... 11. 解析之后得到的aInfo.applicationInfo.packageName的值为quotshy.luo.activityquotaInfo.name的值为quotshy.luo.activity.MainActivityquot这是在这个实例的配置文件AndroidManifest.xml里面配置的。
此外函数开始的地方调用intent.getComponent函数的返回值不为null因此这里的componentSpecified变量为true。
接下去就调用startActivityLocked进一步处理了。
Step 8. ActivityStack.startActivityLocked 这个函数定义在frameworks/base/services/java/com/
android/server/am/ActivityStack.java文件中 java view plaincopy 1. public class ActivityStack 2. 3. ...... 4. 5. final int startActivityLockedIApplicationThread caller 6. Intent intent String resolvedType 7. Uri grantedUriPermissions 8. int grantedMode ActivityInfo aInfo IBinder resultTo 9. String resultWho int requestCode 10. int callingPid int callingUid boolean onlyIfNeeded 11. boolean componentSpecified 12. int err START_SUCCESS 13. 14. ProcessRecord callerApp null 15. if caller null 16. callerApp mService.getRecordForAppLockedcaller 17. if callerApp null 18. callingPid callerApp.pid 19. callingUid callerApp.info.uid 20. else 21. ...... 22. 23. 24. 25. ...... 26. 27. ActivityRecord sourceRecord null 28. ActivityRecord resultRecord null 29. if resultTo null 30. int index indexOfTokenLockedresultTo 31. 32. .......