在Android系统中,Activity和Service是应用程序的核心组件,它们以松耦合的方式组合在一起构成了一个完整的应用程序,这得益于应用框架层提供了一套完整的机制来协助应用程序启动这些Activity和Service,以及提供Binder机制帮助它们相互间进行通信。
在Android系统中,有两种操作会引发Activity的启动,一种用户点击应用程序图标时,Launcher会为我们启动应用程序的主Activity;另一种应用程序的默认Activity启动起来后,它又可以在内部通过调用startActvity接口启动新的Activity,依此类推,每一个Activity都可以在内部启动新的Activity。通过这种连锁反应,按需启动Activity,从而完成应用程序的功能。
这里,我们通过一个具体的例子来说明如何启动Android应用程序的Activity。Activity的启动方式有两种,一种是显式的,一种是隐式的,隐式启动可以使得Activity之间的藕合性更加松散。
Intent intent = new Intent("shy.luo.activity.subactivity");
startActivity(intent);
当然,应用程序框架能够根据名字来找到相应的Activity,是需要应用程序本身来配合的,这就是要通过应用程序的配置文件AndroidManifest.xml来实现了:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="shy.luo.activity"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SubActivity"
android:label="@string/sub_activity">
<intent-filter>
<action android:name="shy.luo.activity.subactivity"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
</manifest>
无论是通过点击应用程序图标来启动Activity,还是通过Activity内部调用startActivity接口来启动新的Activity,都要借助于应用程序框架层的ActivityManagerService服务进程。
我们已经看到,Service也是由ActivityManagerService进程来启动的。在Android应用程序框架层中,ActivityManagerService是一个非常重要的接口,它不但负责启动Activity和Service,还负责管理Activity和Service。
Android应用程序框架层中的ActivityManagerService启动Activity的过程大致如下图所示:
在这个图中,ActivityManagerService 和ActivityStack位于同一进程中,而ApplicationThread和ActivityThread位于另一个进程中。其中,ActivityManagerService是负责管理Activity的生命周期的,ActivityManagerService还借助ActivityStack来把所有的Activity按照后进先出的顺序放在一个堆栈中;对于每一个应用程序来说,都有一个ActivityThread来表示应用程序的主程序,而每一个ActivityThread都包含一个AppllicationThread实例,它是一个Binder对象,负责和其他进程进行通信。
下面简要介绍一下启动的过程:
- 首先在用户进程,当我们调用startActivity(包括Activity或Content 的startActivity),最终都会调用Instrucmentation对象的 execStartActivity 方法
- execStartActivity方法中会调用 IActivityManager 接口的实现对象 ActivityManagerNative 的startActivity 方法。(ActivityManagerNative 是ActivityManagerService 在用户进程中的 代理对象,其实是一个 Binder 对象,用于系统进程向用户进程通讯)
- 因此,startActivity方法会通过代理 调用 ActivityManagerService 的 startActivity 方法。(注意:这里已经切换到系统进程 了)
- ActivityManagerService 的 startActivity 方法经过一系列的校验,最终调用了 IApplicationThread 接口的实例 ApplicationThreadNative 对象的 schudeLaunchActivity 方法(ApplicationThreadNative 对象其实是用户进程的 ApplicationThread 在 系统进程的代理对象,它也是一个Binder 对象,用于系统进程向用户进程通讯)
- 因此,scheduleLaunchActivty 会通过代理调用ApplicationThread 中的 scheduleLaunchActivty 方法。(注意:这里又切换回用户进程)
- scheduleLaunchActivty 方法中调用 sendMessage(H.LAUNCHACTIVITY,r) 方法,通过Handler 发送消息到 ActivityThread (ApplcationThread 其实是 ActivityThread 中的一个内部类,用户进程中使用Handler进行通讯)
- ActivityThread 中 Handler 的 handleeMessage 处理消息,最后调用了 Instrcmentation.newActivity 创建了Activity。