AMS如何杀一个进程呢?何时杀?什么条件下会杀?

博客聚焦于AMS杀进程相关问题,探讨了AMS如何杀进程、在何时杀以及满足什么条件会杀进程,属于信息技术中移动开发相关内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AMS如何杀一个进程呢?何时杀?什么条件下会杀?
<think>我们正在讨论Android系统中的Token机制,特别是ActivityRecord中的Token实例化以及与WindowToken.Builder的区别。根据引用内容,我们知道: 1. ActivityRecord在构造时会创建Token实例(引用[1]): ```java ActivityRecord(...) { appToken = new Token(this, _intent); } ``` 2. ActivityRecord继承了WindowToken(引用[2]),因此它既是Activity在WMS中的表示,又具有WindowToken的功能。 3. Token的创建是在Activity启动过程中,ActivityRecord被创建时发生的(引用[3])。 4. 另外,引用[4]提到,Activity的PhoneWindow拥有token,而Application使用的应用级WindowManager没有token。 现在,我们需要回答两个主要问题: 1. 在什么情况下会通过ActivityRecord的构造方法new Token()? 2. 与WindowToken.Builder的区别是什么? ### 一、Token实例化的触发条件及场景 **触发条件**:当启动一个新的Activity时,ActivityManagerService(AMS)会创建ActivityRecord对象。 **具体场景**: 1. **Activity启动**:无论是通过startActivity()启动Activity,还是系统启动根Activity(如Launcher),都会触发ActivityRecord的创建。 2. **Activity恢复**:当Activity从后台重新回到前台时(例如从最近任务列表恢复),如果进程已经被销毁,系统会重新创建ActivityRecord(进而创建Token)。 3. **配置变更重建**:当Activity因配置变更(如旋转屏幕)而重建时,AMS会重新创建ActivityRecord。 **流程简述**(结合Activity启动流程): - AMS通过`startActivity()`发起启动请求。 - 在AMS内部,会创建目标Activity的ActivityRecord对象(在`ActivityStarter.startActivityLocked()`等方法中)。 - 创建ActivityRecord时,在其构造方法中会实例化Token: ```java appToken = new Token(this, _intent); ``` 这个Token是IApplicationToken.Stub的子类(即一个Binder对象),用于AMS与WMS之间的通信。 **Token的作用**: 1. **标识Activity**:Token作为Activity的唯一标识,AMS和WMS通过Token来管理Activity的状态。 2. **窗口管理**:当Activity需要添加窗口时(如setContentView()),需要将Token传递给WMS,WMS通过Token验证窗口的合法性(防止恶意应用添加伪造窗口)。 3. **通信桥梁**:AMS通过Token通知WMS关于Activity的状态变化(如Activity暂停、销毁等)。 ### 二、与WindowToken.Builder的区别 **WindowToken**:在WMS中,WindowToken代表一组窗口的集合,通常对应一个Token(如Activity的Token)。WindowToken用于管理窗口的层级和显示顺序。 **WindowToken的创建方式**: 1. **通过Token(ActivityRecord)创建**:当ActivityRecord被创建后,AMS会调用WMS的`addAppToken()`方法,将ActivityRecord的Token传递给WMS,WMS会创建一个对应的WindowToken(因为ActivityRecord继承自WindowToken,所以它本身就是WindowToken的一种表现形式,但在WMS内部会有一个映射)。 2. **通过WindowToken.Builder创建**:这是Android 10(API 29)引入的新方式,用于创建非Activity的WindowToken,例如系统窗口、输入法窗口等。 **WindowToken.Builder的使用场景**: ```java // 示例:创建输入法窗口的WindowToken WindowToken token = new WindowToken.Builder(wms, iBinder, type) .setDisplayContent(displayContent) .setOwnerCanManageAppTokens(true) .setRoundedCornerPolicy(policy) .build(); ``` - **系统窗口**:如状态栏、导航栏、输入法窗口等,它们不属于某个特定的Activity。 - **子窗口**:如PopupWindow、ContextMenu等,它们需要附加到父窗口上,但父窗口可能不是Activity(如Application的窗口)。 - **其他特殊窗口**:如Toast、音量面板等。 **区别对比**: | 特性 | ActivityRecord.Token | WindowToken.Builder | |---------------------|------------------------------------------|-----------------------------------------| | **创建者** | ActivityRecord构造方法 | WindowToken.Builder.build() | | **使用场景** | 仅用于Activity | 用于非Activity窗口(系统窗口、子窗口等) | | **绑定关系** | 与ActivityRecord强关联(每个Activity一个) | 与窗口类型关联(可多个窗口共享一个Token)| | **创建时机** | Activity启动时 | 窗口需要时(如添加系统窗口前) | | **Binder对象来源** | 由ActivityRecord构造(new Token()) | 由调用方提供(如输入法服务的Binder) | | **管理方** | AMS管理ActivityRecord,WMS管理对应的WindowToken | 直接由WMS管理 | ### 三、关键流程图示 ```mermaid graph TD A[启动Activity] --> B(AMS创建ActivityRecord) B --> C[new Token()] C --> D[AMS调用WMS.addAppToken()] D --> E[WMS创建/获取WindowToken] F[添加系统窗口] --> G(调用方创建Binder) G --> H[使用WindowToken.Builder] H --> I[WMS.addWindowToken()] ``` ### 四、为什么需要两种方式? 1. **Activity窗口的特殊性**:Activity窗口有严格的生命周期(由AMS管理),需要与ActivityRecord紧密绑定。 2. **系统窗口的灵活性**:系统窗口可能由多个组件共享(如多个输入法窗口共享一个Token),且没有Activity的生命周期概念。 3. **安全性**:Activity的Token由AMS统一分配,确保不可伪造;系统窗口的Token由系统服务提供,同样需要验证。 ### 五、典型问题分析 **问题**:为什么Application的WindowManager添加窗口时没有Token? **回答**:因为Application没有ActivityRecord,也就没有Token。此时添加的窗口属于应用级窗口,没有与Activity关联,所以无法通过WMS的Token验证(可能导致Z-order问题,如无法覆盖Activity窗口)。 **解决方法**:为窗口指定`TYPE_APPLICATION_OVERLAY`类型(需要权限),此时系统会使用WindowToken.Builder为其创建Token。 --- ### 相关问题 1. **Activity的Token在Activity销毁后会被复用吗?** 2. **如何通过adb命令查看当前活动的WindowToken?** 3. **WindowToken.Builder在创建系统窗口时如何确保安全性?** 4. **ActivityRecord.Token与WindowToken在WMS中的存储方式有何不同?** 5. **为什么子窗口(如PopupWindow)不需要指定Token?**</think>### Android Token 实例化机制深度解析 #### 一、Token() 实例化的触发条件及场景 **核心触发条件**:当系统需要创建新的 Activity 实例时,会通过 AMS(Activity Manager Service)创建对应的 ActivityRecord 对象,此时触发 Token 实例化[^1][^3]。 **具体场景**: 1. **Activity 启动时**: ```mermaid graph LR A[Activity启动请求] --> B(AMS创建ActivityRecord) B --> C[new Token()实例化] C --> D[Token绑定到ActivityRecord] ``` - 当通过 `startActivity()` 启动新 Activity 时 - 系统恢复被销毁的 Activity(如配置变更重建) 2. **系统创建根 Activity**: - 应用冷启动时首个 Activity 的创建 - Launcher 启动应用时的主 Activity 3. **特殊场景**: - 多窗口模式下新建 Activity 实例 - 分屏模式下创建新 Activity **关键代码流程**: ```java // ActivityStarter.java void startActivityLocked(...) { // 创建ActivityRecord final ActivityRecord r = new ActivityRecord(...); // [^3] } // ActivityRecord.java ActivityRecord(...) { // 在此处实例化Token appToken = new Token(this, _intent); // [^1] } ``` #### 二、Token 与 WindowToken.Builder 的区别 | **特性** | **ActivityRecord.Token** | **WindowToken.Builder** | |------------------------|---------------------------------------------|---------------------------------------------| | **创建者** | AMS 在创建 ActivityRecord 时自动生成 | WMS(WindowManagerService)显式构建 | | **使用场景** | 仅用于 Activity 窗口 | 用于非 Activity 窗口(系统窗口/Toast 等) | | **绑定关系** | 与 ActivityRecord 强绑定 | 与窗口类型(如 TYPE_TOAST)绑定 | | **生命周期** | 随 Activity 销毁而释放 | 独立管理,需显式移除 | | **创建方式** | `new Token()` 直接实例化 | Builder 模式构建:`new WindowToken.Builder().build()` | | **Binder 通信对象** | IApplicationToken.Stub | IBinder(通用接口) | **WindowToken.Builder 典型使用场景**: ```java // 系统创建Toast窗口时 WindowToken token = new WindowToken.Builder(mWms, binder, type) .setDisplayContent(displayContent) .setOwnerCanManageAppTokens(true) .build(); // [^4] ``` #### 三、核心差异解析 1. **功能定位差异**: - `Token` 是 Activity 的**身份凭证**,用于 AMS-WMS 通信验证 $$ \text{ActivityRecord} \xrightarrow{\text{1:1}} \text{Token} $$ - `WindowToken` 是窗口的**分组标识**,用于管理窗口层级 $$ \text{WindowType} \xrightarrow{\text{1:N}} \text{WindowToken} $$ 2. **创建机制差异**: ```mermaid sequenceDiagram participant AMS participant WMS AMS->>WMS: addAppToken(token, displayId) Note over WMS: 将Token映射为WindowToken WMS->>WMS: new WindowToken.Builder().forAppToken().build() ``` - Token 在 AMS 侧创建后传递给 WMS - WindowToken.Builder 由 WMS 直接创建 3. **窗口验证机制**: - Activity 窗口:通过 `LayoutParams.token` 验证是否匹配 ActivityRecord - 系统窗口:通过 `WindowToken` 的 Binder 对象验证权限 #### 四、关键设计原理 1. **Token 的安全隔离**: ```java // WMS 验证窗口合法性 boolean validateToken(WindowState win) { return (win.mAttrs.token == activityRecord.token); // [^4] } ``` 防止恶意应用伪造窗口覆盖系统界面 2. **WindowToken 的层级管理**: - 同类型窗口共享同一 WindowToken - 确保系统窗口(状态栏/导航栏)始终置顶 3. **生命周期同步**: - Activity 销毁时自动移除关联 Token $$ \text{Activity.onDestroy()} \rightarrow \text{AMS.removeActivity()} \rightarrow \text{WMS.removeToken()} $$ --- ### 相关问题 1. **为什么 Dialog 需要 Activity Context 才能正确显示?** 2. **如何通过 ADB 命令查看当前活动的 WindowToken?** 3. **Token 机制如何防止窗口劫持攻击?** 4. **WindowToken.Builder 在创建系统通知窗口时的具体流程是什么?** 5. **ActivityRecord 被销毁后,其对应的 Token 会立即释放吗?** 6. **多显示器场景下 Token 的管理机制有何特殊设计?**
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值