本文主要对安卓中进程的一个介绍,以及一些知识的科普。
阅读本文,可以帮你解答以下几个问题:
1.安卓系统有哪些服务。
2.为什么手机上没有打开任何一个引用,但是系统内存却已经使用了很多。
3.安卓的应用进程由谁生成。
我们可以通过adb命令:adb shell ps > ps.txt导出一份安卓应用进程文件,其部分内容如下:
- USER PID PPID VSZ RSS WCHAN ADDR S NAME
- root 1 0 2319696 8084 0 0 S init
- root 2 0 0 0 0 0 S [kthreadd]
- root 3 2 0 0 0 0 I [rcu_gp]
- root 310 1 2289352 4436 0 0 S init
- u0_a81 353 1520 5858304 106084 0 0 S com.heytap.openid
- system 1040 1 2153044 5020 0 0 S servicemanager
- system 1303 1 2433864 6136 0 0 S android.system.suspend@1.0-service
- keystore 1304 1 2602468 13864 0 0 S keystore2
- tombstoned 1368 1 2126624 3136 0 0 S tombstoned
- root 1520 1 6138208 148784 0 0 S zygote64
- root 1521 1 1801468 61636 0 0 S zygote
- audioserver 1592 1 3565804 13400 0 0 S android.hardware.audio.service_64
- gpu_service 1830 1 2349128 5624 0 0 S gpuservice
- system 1835 1 3808932 134676 0 0 S surfaceflinger
- u0_a404 2105 1520 6647556 167056 0 0 S com.whatsapp
- u0_a188 4351 1520 8760400 457416 0 0 S com.android.systemui
- webview_zygote 4564 1521 1749980 17420 0 0 S webview_zygote
- u0_a178 4703 1520 8375780 314520 0 0 S com.android.launcher
- system 4807 1520 6352940 110272 0 0 S com.oplus.notificationmanager
- system 7402 1520 7194740 159872 0 0 S com.oplus.battery
-
- u0_a311 7085 1520 8340428 164928 0 0 S com.tencent.mm:push
- u999_a311 11870 1520 8285364 158096 0 0 S com.tencent.mm:push
- u999_a311 12172 1520 26825040 266652 0 0 S com.tencent.mm
- u0_a311 31989 1520 146617368 411492 0 0 S com.tencent.mm
-
- u0_a120 13476 1520 24472076 236484 0 0 S com.baidu.input_oppo
- shell 17369 1 2408000 6088 0 0 S adbd
- system 23451 1520 6020924 119656 0 0 S com.oplus.securitypermission
- u0_a372 32704 1520 24923448 263656 0 0 S cn.damai
- 总数量有800多个进程
字段含义:
字段名 | 解释 |
USER | 所属用户,一般来说,同一个签名下的应用属于同一个用户。 |
PID | 进程ID |
PPID | 父亲进程的ID |
VSZ | 进程的虚拟内存大小 |
RSS | 当前在物理内存中占用的空间大小 |
WCHAN | 当前正在等待的事件或条件 |
ADDR | 表示进程的起始内存地址 |
S(State) | 表示进程的当前状态。包括:R(运行),S(睡眠),D(不可中断的睡眠),I(空闲)等 |
NAME | 进程名 |
这里我们扩展介绍下USER字段,主要区别以下ROOT和SYSTEM用户,正如其字面意思,ROOT代表的是超级用户,拥有的是最高权限,具有完全控制权。而SYSTEM代表是系统用户,拥有的是较高权限,但并不是完全的控制权。一般来说,系统级的应用都属于SYSTEM用户。
一些主要的进程介绍:
NAME | USER | PID | PPID | 介绍 |
init | root | 1 | 0 | init进程,安卓系统的大儿子。其PID一定为1。 |
kthreadd | root | 2 | 0 | 内核线程守护进程,它是Linux内核的一部分,负责创建和管理其他内核线程 |
rcu_gp | root | 3 | 2 | 内核进程,这一类的还有很多,都是由kthreadd创建 |
init | root | 310 | 1 | 有PID=1的init进程fork生成,负责执行一些特定的任务 |
com.heytap.openid | u0_a81 | 353 | 1520 | 这是一个系统级的应用,我们APP中经常会需要唯一标识符openId,就是由这个应用提供的。 这里为什么它的PID比其父进程zygote64还小呢?答案留到最后 |
servicemanager | system | 1040 | 1 | 系统服务进程,类似于系统中的一个路由,当需要某个服务时,先向这个路由进行访问,其生成时间早于zogyte。 |
zygote64 | root | 1520 | 1 | 和zygote功能类似,但是这个进程是针对64位应用的 |
zygote | root | 1521 | 1 | zygote进程,所有的应用进程都是由该进程孵化的。 |
android.hardware.audio.service_64 | audioserver | 1592 | 1 | 负责处理与音频功能相关的服务和任务 |
gpuservice | gpu_service | 1830 | 1 | 负责管理和控制图形处理单元(GPU)的功能和资源 |
surfaceflinger | system | 1835 | 1 | 负责管理和显示屏幕上所有图形和图层的任务。所有APP的最终刷新频率和绘制都是由其负责的。 |
com.whatsapp | u0_a404 | 2105 | 1520 | 这就是一个正常的聊天应用,所以其parentId=1520,其PID=2105应该是进程ID复用了。 |
com.android.systemui | u0_a188 | 4351 | 1520 | 负责一些系统级的展示,最常用的就是toast的展示就是由其负责的。 |
webview_zygote | webview_zygote | 4564 | 1521 | 我们APP中使用webView组件,其实APP只是通知了webview_zygote,解析html以及渲染的逻辑都是由webview_zygote完成的。 |
com.android.launcher | u0_a178 | 4703 | 1520 | 我们的桌面应用 |
com.oplus.notificationmanager | system | 4807 | 1520 | 通知栏应用 |
com.oplus.battery | system | 7402 | 1520 | 推测应该是电源管理类的应用 |
com.tencent.mm:push | u0_a311 | 7085 | 1520 | 负责处理推送的微信进程 |
com.tencent.mm:push | u999_a311 | 11870 | 1520 | 负责处理推送的微信进程 |
com.tencent.mm | u999_a311 | 12172 | 1520 | 微信 |
com.tencent.mm | u0_a311 | 31989 | 1520 | 微信,这里为什么会有两个呢?第三章会讲 |
com.baidu.input_oppo | u0_a120 | 13476 | 1520 | 输入法 |
adbd | shell | 17369 | 1 | 我们的adb命令得以执行,是因为手机上有一个服务在处理我们输入的命令。 |
com.oplus.securitypermission | system | 23451 | 1520 | 系统级的应用,应该是权限管理一类的。 |
cn.damai | u0_a372 | 32704 | 1520 | 虽然大麦在页面上的显示进程已经被杀死了,但是系统进程中仍然还存在。 感觉这属于一加系统故意的设置 |
com.xt.myapp | u0_a379 | 32707 | 1520 | 这是我自定义的应用,是一个普通的应用,退出后会被彻底杀死 |
我们可以通过adb命令:adb shell dumpsys activity services > service.txt导出一份service运行列表文件,获取当前处于活跃状态的service。
其部分内容如下:
- ACTIVITY MANAGER SERVICES (dumpsys activity services)
- * ServiceRecord{4f884ba u0 com.oplus.battery/.OplusBatteryService}
- intent={act=com.oplus.battery.OplusBatteryService pkg=com.oplus.battery}
- packageName=com.oplus.battery
- processName=com.oplus.battery
- permission=com.oplus.permission.safe.READ_COMMON
- baseDir=/system_ext/app/Battery/Battery.apk
- dataDir=/data/user_de/0/com.oplus.battery
-
- * ServiceRecord{3015c51 u0 com.android.launcher/com.android.keyguardservice.KeyGuardDismissedService}
- intent={act=com.android.launcher.action.KeyGuardDismissedService cmp=com.android.launcher/com.android.keyguardservice.KeyGuardDismissedService}
- packageName=com.android.launcher
- processName=com.android.launcher
- permission=oplus.permission.OPLUS_COMPONENT_SAFE
- baseDir=/system_ext/priv-app/OplusLauncher/OplusLauncher.apk
- dataDir=/data/user_de/0/com.android.launcher
- app=ProcessRecord{d41799e 4703:com.android.launcher/u0a178}
-
- * ServiceRecord{d4df27a u0 com.tencent.mobileqq/.winkpublish.service.WinkPublishService}
- intent={cmp=com.tencent.mobileqq/.winkpublish.service.WinkPublishService}
- packageName=com.tencent.mobileqq
- processName=com.tencent.mobileqq
- baseDir=/data/app/~~zynQ-ZG3_WwINWYGDBfM2g==/com.tencent.mobileqq-vEZqX7KombL9LhGhkQYEWw==/base.apk
- dataDir=/data/user/0/com.tencent.mobileqq
- app=ProcessRecord{7a090aa 8840:com.tencent.mobileqq/u0a383}
- allowWhileInUsePermissionInFgs=true
- recentCallingPackage=com.tencent.mobileqq
- recentCallingUid=10383
- allowStartForeground=ACTIVITY_STARTER
- startForegroundCount=0
- infoAllowStartForeground=[callingPackage: com.tencent.mobileqq; callingUid: 10383; uidState: SVC ; intent: Intent { cmp=com.tencent.mobileqq/.winkpublish.service.WinkPublishService }; code:ACTIVITY_STARTER; tempAllowListReason:<,reasonCode:SYSTEM_ALLOW_LISTED,duration:9223372036854775807,callingUid:-1>; targetSdkVersion:26; callerTargetSdkVersion:26; startForegroundCount:0; bindFromPackage:null]
- createTime=-1h37m30s314ms startingBgTimeout=--
- lastActivity=-4m25s954ms restartTime=-47m19s338ms createdFromFg=false
- Bindings:
- * IntentBindRecord{6d2ae21 CREATE}:
- intent={cmp=com.tencent.mobileqq/.winkpublish.service.WinkPublishService}
- binder=android.os.BinderProxy@7486246
- requested=true received=true hasBound=true doRebind=false
- * Client AppBindRecord{fe75c07 ProcessRecord{7a090aa 8840:com.tencent.mobileqq/u0a383}}
- Per-process Connections:
- ConnectionRecord{ff84ea5 u0 CR com.tencent.mobileqq/.winkpublish.service.WinkPublishService:@4dd249c}
- All Connections:
- ConnectionRecord{ff84ea5 u0 CR com.tencent.mobileqq/.winkpublish.service.WinkPublishService:@4dd249c}
-
-
- 共有253的service
我们可以看到,有的service所属的APK目录不一致,分别有以下几种:
目录 | 介绍 |
/system/app/ | 该目录下的应用是预装在设备上的系统应用程序,一般是系统开发商或者设备制造商定制。 |
/my_bigball/priv-app/ | my_bigball应该是一加定制的,其实应该是system/priv-app/,该目录下的应用通常是敏感或核心的系统应用程序,提供了更高的特权和权限。 |
/system_ext/app/ | 顾名思义,应该是设备制造商提供的具有扩展功能的系统级应用 |
/vendor/app/ | 由设备供应商定制的系统级应用 |
使用一部手机的时候,你会发现没有打开任何一个应用,但是往往16G的内存已经使用了6个G甚至更多,这是为什么呢?主要分为两块:
第一块系统进程,安卓系统中并不是只有应用进程,它还有众多的系统进程,这些进程虽然没有前台展示给用户看,但是确实一直运行的。
第二块应用后台服务,而且我们经常使用到的微信支付/支付宝支付等等也都会默认在后台运行,所以其对应的进程自然也会存在。比如第二章中,我们发现QQ的后台服务就一直存活中。
com.tencent.mobileqq/.winkpublish.service.WinkPublishService
第一章中,我们发现大麦APP彻底退出后,甚至于点击菜单栏看不到任何运行中的进程,但是通过ps查看进程,发现大麦进程仍然存活。另外,我们还发现竟然有两个微信进程,这明显不合理。
- u0_a372 32704 1520 24923448 263656 0 0 S cn.damai
-
- u0_a311 7085 1520 8340428 164928 0 0 S com.tencent.mm:push
- u999_a311 11870 1520 8285364 158096 0 0 S com.tencent.mm:push
- u999_a311 12172 1520 26825040 266652 0 0 S com.tencent.mm
- u0_a311 31989 1520 146617368 411492 0 0 S com.tencent.mm
但是如果是普通的应用,比如com.xt.myapp,应用彻底退出后进程就会被杀死。
这一块无法解释,如果直接使用安卓模拟器是没有这问题的,所以只能说明一加的手机做了魔改,并且产生了一些副作用。
比如第一章的例子中,com.heytap.openid的PID就比zoygte的1520还小。
- root 1520 1 6138208 148784 0 0 S zygote64
- u0_a81 353 1520 5858304 106084 0 0 S com.heytap.openid
这是因为PID进程不可能无限增长下去,所以当某个进程完全死亡后,其进程标识符(PID)可以被系统重新分配给新的进程。这里很明显,com.heytap.openid使用了重新分配的PID。