一、Activity的启动过程及源码解析

1.两种启动操作

a.用户点击应用程序图标

 在Android系统中,应用程序是由launcher启动起来的,其实,Laucher本身也是一个应用程序,其他的应用程序安装后,就会在Laucher界面上出现一个相应的图标,点击这个图标是,Laucher就会对应的应用程序启动起来

b.应用程序的默认Activity启动起来后,通过调用startActivity接口启动新的Activity,以此类推,每一个Activity都可以在内部启动新的Activity

2.a的源码分析

 a.Launcher通过Binder进程间通信机制通知ActivityMangerService,它要启动一个Activty(step1-step11)

       Step 1. Launcher.startActivitySafely,Launcher继承于Activity类,调用了Activity.startActivity函数src/com/android/launcher2/Launcher.java

       Step 2. Activity.startActivity,它调用startActivityForResult来进一步处理(frameworks/base/core/java/android/app/Activity.java)

        Step 3. Activity.startActivityForResult,通过ActivityThread.getApplicationThread获得它里面的ApplicationThread成员变量,它是一个Binder对象

        Step 4. Instrumentation.execStartActivity,通过ActivityManagerNative.getDefault返回ActivityManagerService的远程接口即ActivityManagerProxy接口。Intrumentation它用来监控应用程序和系统的交互。(frameworks/base/core/java/android/app/Instrumentation.java)

        Step 5. ActivityManagerProxy.startActivity,通过Binder驱动程序就进入到ActivityManagerService的startActivity函数,(frameworks/base/core/java/android/app/ActivityManagerNative.java)

       Step 6. ActivityManagerService.startActivity,将操作转发给成员变量ActivityStack的startActivityMayWait函数(frameworks/base/services/java/com/android/server/am/ActivityManagerService.java

      Step 7. ActivityStack.startActivityMayWait,得到要打开Activity的相关信息,保存在ActivityInfo变量中,调用startActivityLocked进一步处理(frameworks/base/services/java/com/android/server/am/ActivityStack.java)

      Step 8. ActivityStack.startActivityLocked,得到并保存调用者的进程信息在ProcessRecord中,即Launcher应用程序的进程信息了。获得并Launcher这个Activity的相关信息保存在ActivityRecord中。接着调用startActivityUncheckedLocked函数,

       Step 9. ActivityStack.startActivityUncheckedLocked,首先获得并保存intent的标志值;通过findTaskLocked函数来查找可用Task,没有就新建并保存在ActivityManagerService中;通过topRunningActivityLocked判断堆栈顶端的Activity是否就是即将要启动的Activity,不是则要新建

        Step 10. Activity.resumeTopActivityLocked,将获得堆栈顶端确定是要打开的Activity保存在ActivityRecord,并保存栈顶Activity可用的状态(useleaving);然后看要启动的Activity是否处在栈顶端并且是当前处理Resumed状态的Activity,如果不是的话下判断当前是否有Activity正在进入Pausing状态,如果有的话,当前这个Resumed状态的Activity就要稍后才能进入Paused状态了,这样就保证了所有需要进入Paused状态的Activity串行处理。

    Step 11. ActivityStack.startPausingLocked,把Launcher保存在ActivityRecord中。取出Launcher进程中的ApplicationThread对象,并通过其对象的远程接口schedulePauseActivity来通知Launcher进入Paused状态。

b.ActivityMangerService通过Binder进程间通信机制通知Laucher进入Paused状态(step12-step16)

     Step 12. ApplicationThreadProxy.schedulePauseActivity,过Binder进程间通信机制进入到ApplicationThread.schedulePauseActivity函数中(frameworks/base/core/java/android/app/ApplicationThreadNative.java)

     Step 13. ApplicationThread.schedulePauseActivity,是ActivityThread的内部类,调用函数queueOrSendMessage,(frameworks/base/core/java/android/app/ActivityThread.java)

     Step 14. ActivityThread.queueOrSendMessage,将相关信息组装成一个msg并通过Handler(H)成员变量发送出去,是ActivityThread的内部类,这个消息最后由H.handleMessage来处理。

     Step 15. H.handleMessage,调用ActivityThread.handlePauseActivity进一步操作

    Step 16. ActivityThread.handlePauseActivity,首先将Binder引用的IBinder(token)转换成ActivityClientRecord()ActivityRecord的远程接口)然后做了三个事情:1. 如果保存栈顶Activity可用的状态(userLeaving)为true,则通过调用performUserLeavingActivity函数来调用Activity.onUserLeaveHint通知Activity用户要离开它了;2. 调用performPauseActivity函数来调用Activity.onPause函数(让位于其它的Activity)3. 它通知ActivityManagerService,这个Activity已经进入Paused状态了,ActivityManagerService可以启动Activity了。

c.Laucher通过Binder进程间通信机制通知ActivityMangerService,它已经准备就绪进入Paused状态,于是ActivityManagerService就创建一个新的进程,用来启动一个ActivityThread实例,即将要启动的Activity就是在这个ActivityThread实例中运行(step17-step24)

   Step 17. ActivityManagerProxy.activityPaused, 通过Binder进程间通信机制就进入ActivityManagerService.activityPaused

   Step 18. ActivityManagerService.activityPaused,进入到ActivityStack.activityPaused

   Step 19. ActivityStack.activityPaused,通过IBinder(token)在mHistory列表中得到ActivityRecord(Launcher),而我们在Step 11中,保存了Launcher这个Activity(mPausingActivity),于是执行completePauseLocked。

   Step 20. ActivityStack.completePauseLocked,清空mPausingActivity变量,调用resumeTopActivityLokced

   Step 21. ActivityStack.resumeTopActivityLokced,调用topRunningActivityLocked取出即将要启动的堆栈顶端Activity,保存在next(ActivityRecord)中。mResumedActivity为null,MainActivity的ProcessRecord域的一直保持为null。调用startSpecificActivityLocked

   Step 22. ActivityStack.startSpecificActivityLocked,取回来的ProcessRecord为null,调用ActivityManagerService.startProcessLocked。

没有指定Application标签的process属性,系统就会默认使用package的名称,每一个应用程序都有自己的uid,因此这里uid + process的组合就可以为每一个应用程序创建一个ProcessRecord。当然,我们可以配置两个应用程序具有相同的uid和package不同的应用程序也可以在同一个进程中启动。     

   Step 23. ActivityManagerService.startProcessLocked,检查是否已经有以process + uid命名的进程返回值ProcessRecord为null,因此后面会创建一个ProcessRecord,并存保存在为成员变量(mProcessNames),最后调用另一个startProcessLocked函数去调用Process.start接口创建新的进程,会导入ActivityThread类并且执行它的main函数,

每一个应用程序都有一个ActivityThread实例来对应

   Step 24. ActivityThread.main,创建一个ActivityThread实例,调用它的attach函数,接着就进入消息循环了,直到最后进程退出。函数attach调用了ActivityManagerProxy.attachApplication

d.ActivityThread通过Binder进程间通信机制将一个ApplicationThread类型的Binder对象传递给ActivityManagerService,以便以后ActivityManagerService能够通过这个Binder对象和它进行通信(step25-step27)

     Step 25. ActivityManagerProxy.attachApplication,通过Binder驱动程序进入ActivityManagerService.attachApplication

     Step 26. ActivityManagerService.attachApplication,将操作转发给attachApplicationLocked函数

     Step 27. ActivityManagerService.attachApplicationLocked,通过pid取出ProcessRecord,放在ProcessRecord变量并对它的其它成员进行初始化,最后调用mMainStack.realStartActivityLocked执行真正的Activity启动操作。

e.Acti vityManagerService通过Binder进程间通信机制通知ActivityThread,现在一起准备就绪,它可以真正执行Activity的启动操作(step28-step35)

   Step 28. ActivityStack.realStartActivityLocked,进入到ApplicationThreadProxy.cheduleLaunchActivity

   Step 29. ApplicationThreadProxy.scheduleLaunchActivity,通过Binder驱动程序进入到ApplicationThread.scheduleLaunchActivity

   Step 30. ApplicationThread.scheduleLaunchActivity,创建一个ActivityClientRecord实例,并且初始化它的成员变量,后调用ActivityThread.queueOrSendMessage

   Step 31. ActivityThread.queueOrSendMessage,把消息内容放在msg(Message)中,然后通过mH(Hander)把消息分发出去

    Step 32. H.handleMessage,调用ActivityThread.handleLaunchActivity

   Step 33. ActivityThread.handleLaunchActivity,调用performLaunchActivity来加载这个Activity类,然后调用它的onCreate函数,最后回到handleLaunchActivity函数再调用handleResumeActivity函数来使这个Activity进入Resumed状态(Activity.onResume)

   Step 34. ActivityThread.performLaunchActivity,收集要启动的Activity的信息(package、component),然后通过ClassLoader将MainActivity类加载进来,接下来是创建Application对象,后面创建Activity的上下文信息,并通过attach方法将这些上下文信息设置到MainActivity中去,最后调用mInstrumentation.callActivityOnCreateMainActivity来间接调用(MainActivity.onCreate )      

    Step 35. MainActivity.onCreate,这样MainActivity就启动起来了,整个应用程序也启动起来了。





 
 


猜你喜欢

转载自blog.csdn.net/qq_25283953/article/details/80914536