StevGuo系列文章翻译之Talking about Android process


通过这个篇文章,我们会了解关于Android进程管理的相关信息。首先我们看一下Android完成boot后加载的进程:

USER PID PPID VSIZE RSS WCHAN PC NAME

root 1 0 264 176 c00acc6c 0000c36c S /init

root 28 1 724 308 c0051354 afe0c4cc S /system/bin/sh

system 30 1 796 248 c026516c afe0b74c S /system/bin/servicemanager

root 31 1 1824 316 ffffffff afe0b50c S /system/bin/mountd

root 32 1 652 248 c02976e0 afe0c0bc S /system/bin/debuggerd

radio 33 1 5344 664 ffffffff afe0bdbc S /system/bin/rild

root 34 1 71028 18828 c00ad308 afe0b874 S zygote

media 37 1 16812 3456 ffffffff afe0b74c S /system/bin/mediaserver

root 39 1 788 288 c02f9ae4 afe0b50c S /system/bin/installd

system 86 34 187756 21836 ffffffff afe0b74c S system_server

radio 118 34 103476 13896 ffffffff afe0c824 S com.android.phone

app_4 124 34 117848 19248 ffffffff afe0c824 S android.process.acore

app_5 139 34 98672 11516 ffffffff afe0c824 S com.android.mms

app_3 151 34 92096 10976 ffffffff afe0c824 S com.android.alarmclock

app_6 161 34 94436 12616 ffffffff afe0c824 S com.android.calendar

app_9 173 34 93248 11728 ffffffff afe0c824 S android.process.media

app_15 182 34 91848 9764 ffffffff afe0c824 S com.android.voicedialer

app_16 190 34 94524 10812 ffffffff afe0c824 S android.process.im

我们分几部分来说。

 

Root进程。

 

Init是内核booting后的第一个进程。它的主要任务是:

1、       解析并执行init.rcinit.%hardware%.rc

2、       自动生成/dev下的设备节点。

3、       开户logproperty服务。

4、       监视设备、property set以及子进程退出事件。

5、        

Native Application进程。

 

通过init.rcinitfork出下面的native application进程:

Console:启动shell

ServiceManager:开启binder IPC Service Manager.

Mountd:挂载/system/etc/mountd.conf中定义的fs,接收本地socket中挂载任意fs的命令。

Debuggerd:开启debug系统。

Rild:开启radio接口层的daemon

Zygote:启动AndroidJava VM Runtime和系统服务。它是最重要的进程。

Mediaserver:开启AudioFlingerMediaPlayerServiceCameraService

Installd:开启安装包的daemon

 

Java Application进程

 

每一个Java Application进程都是从zygote进程中fork出来的。System_server是一个特殊Java进程,它直接从zygote进程中fork出来,而其它的Java进程是从ActivityManagerService中创建的。ActivityManagerService是运行在system_server进程中的。ActivityManagerService创建Java进程的过程就像下面描述的这样:

int pid = Process.start("android.app.ActivityThread",

mSimpleProcessManagement ? app.processName : null, uid, uid,

gids, ((app.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0), null);

Process.java是使用UNIX domain socketzygote通信的。看看下面这张图。

 

System Server

 

它是第一个被zygote加载的Java application。它开启Android最核心的服务:

ActivityManager,WindowManager,PackageManager等。因此,它是Android系统启动的源头。

 

Persistent Application

 

booting期间,ActivityManagerService.systemReady会启动下面这些Persistent

Application.

List apps = ActivityThread.getPackageManager().

getPersistentApplications(PackageManager.GET_SHARED_LIBRARY_FILES);

if (apps != null) {

int N = apps.size();

int i;

for (i=0; i<N; i++) {

ApplicationInfo info

= (ApplicationInfo)apps.get(i);

if (info != null &&

!info.packageName.equals("android")) {

addAppLocked(info);

}

}

}

现在只有Phone application被注册为persistent application。注册方式是在AndroidManifest.xml中:

<application android:name="PhoneApp"

android:persistent="true"

android:label="@string/dialerIconLabel"

android:icon="@drawable/ic_launcher_phone">

(大兵注:android:persistent属性为true表示这个application在任何时候都应该运行,一旦它被意外强行中止,系统会立即重启。而false则表示这是一个一般的应用程序,通常只有一少部分系统程序应该标记为true

这样,在booting过程中,只有phone application被自动加载。这就是前面进程列表中我们看到的com.android.phone进程。)

 

第一个Activity

 

第一个Activity是通过从ActivityManagerService中发送含有Intent.CATEGORY_HOMEIntentlaunch的。

Intent intent = new Intent(

mTopAction,

mTopData != null ? Uri.parse(mTopData) : null);

intent.setComponent(mTopComponent);

if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {

intent.addCategory(Intent.CATEGORY_HOME);

}

ActivityInfo aInfo =

intent.resolveActivityInfo(mContext.getPackageManager(),

PackageManager.GET_SHARED_LIBRARY_FILES);

if (aInfo != null) {

intent.setComponent(new ComponentName(

aInfo.applicationInfo.packageName, aInfo.name));

// Don't do this if the home app is currently being

// instrumented.

ProcessRecord app = getProcessRecordLocked(aInfo.processName,

aInfo.applicationInfo.uid);

if (app == null || app.instrumentationClass == null) {

intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);

startActivityLocked(null, intent, null, null, 0, aInfo,

null, null, 0, 0, 0, false);

}

}

它就是android.process.acore进程,进程的名字被定义在AndroidManifest.xml.

 

Booting后被自动加载的程序

 

ActivityManagerService检测到activity idle时,它会广播含有ACTION_BOOT_COMPLETEDIntent

if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {

// Tell anyone interested that we are done booting!

synchronized (this) {

broadcastIntentLocked(null, null,

new Intent(Intent.ACTION_BOOT_COMPLETED, null),

null, null, 0, null, null,

android.Manifest.permission.RECEIVE_BOOT_COMPLETED,

false, false, MY_PID, Process.SYSTEM_UID);

}

}

现在,MMS,AlarmClock,Calendar,MediaProvider,VoiceDialer,IM都已经成为注册了一个接收ACTION_BOOT_COMPLETEDReceiver。所以它们都会被自动加载。

Email也注册了,但是它还有另外一个属性android:enable=”false”,所以它不会被加载。

<receiver android:name=".service.BootReceiver"

android:enabled="false"

>

<intent-filter>

<action android:name="android.intent.action.BOOT_COMPLETED" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.DEVICE_STORAGE_LOW" />

</intent-filter>

<intent-filter>

<action android:name="android.intent.action.DEVICE_STORAGE_OK" />

</intent-filter>

</receiver>

(大兵注:android:exported属性表示这个Receiver是否接收外部发送的Intent,如果是true的话表示可以,如果是false,那么这个Receiver只能接收两种来源的消息,自己所属的application或者那些有相同user IDapplication。如果这个Receiver中不含有任何fileters,那么它就只能接收含有明确Receiver类名的Intent,意味着这个Receiver只是在application内部使用。这时,默认值就是false。只要有一个filter指明这个Receiver接收来自系统或者其它applicationintent,那么默认值就是true.如果想控制Receiver的暴露性,这个属性不是唯一的手段,可以看一下<receiver>android:permission

 

Java进程的背后

 

System_server是一个特例。它可以调用ActivityThread.javasystemMain静态方法,这个方法会创建一个ActivityThread实例。然后,这个ActivityThread实例就会创建一个ApplicationThread,Application,ApplicationContext实例。

其它的java进程,工作的方式各自不同,都由zygotefork但由system_server控制。除了system_server外的任何一个java进程被fork时,都会自动调用ActivityThread.javamain方法,可以看一下Process.java或者下面这个代码段:

try {

ZygoteInit.invokeStaticMain(cloader, className, mainArgs);

} catch (RuntimeException ex) {

logAndPrintError (newStderr, "Error starting. ", ex);

}

ApplicationThread会用Ibinder机制与system_server中的ActivityManagerService交互。这个新进程会等待来自system_server的调用。而ApplicationApplicationContext不会在这时被创建,在进程真正工作的时候才被创建。

例如,当开启一个activity时,ActivityManagerService知道这个activity应该运行在哪个进程,所以它会通过RPC机制调用ApplicationThreadscheduleLaunchActivity方法来在那个进程中加载这个新的activity。然后,ApplicationThreadpost一个message来让ActivityThread知道它需要开启一个activity。然后,ActivityThread会创建ApplicationApplicationContext对象并调用Instrumentation,最后Instrumentation调用Java dalvik VM真正创建一个activityjava对象。

你可能感兴趣的:(java,android,null,application,System)