coreApp=true属性及android4.2下多用户进程启动说明

本文探讨了Android系统中coreApp=true属性的意义及其作用,详细解释了核心APP的概念及启动机制,并介绍了多用户环境下system权限APP的行为差异。

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

1.      关于coreApp=true的说明,在manifest中增加该属性,其实并不是代表该APP具有系统权限,而是把该类app归类为核心APP,核心app其实也是最小android framework系统。那么核心APP的作用是什么呢?在Android3.0之后,Android就增加了加密机制(可以加密机制是可选的,目前R70并没有打开),当系统开机时检测到系统加密,他就把核心APP全部启动,并显示UI提供用户输入密码,密码正确后才会启动完整系统。

android加密部分的说明可以参考下面文章;
http://blog.csdn.net/magod/article/details/7928090

 

2.      在多用户系统下,我们会看到一些进程始终只有一个,比如system_process, android系统有两种方式其他system server。

1.在init.rc启动system server,从init.rc启动的system server是永远只会有一个进程的。

 

2.通过 framework中的api启动,这个会调用的dalvik中的native code。在dalivk的native code中会在去判断请求属于system server还是普通app进程。

 

                  

普通的app,即没有增加sharedUserId="android.uid.system"属性这些,

在系统默认启动后,我们看到可能就是u0_a10,新增用户下,启动后看到的就是u10_a10。

而通过api启动的system server进程有两情况,一种就是类似init.rc的方式,只有一个进程;另外一种也会两个进程。

只有一个进程的是由什么决定的呢?有两个方面的因素:

1.必须有系统权限,即有sharedUserId="android.uid.system"属性

2.必须有android:persistent="true"属性,也就该进程常驻系统,永远不会被杀掉。

当具备上面两个属性时,即使在多用户下,启动带该属性的app,也只会有一个进程,该进程的用户为system。

Android系统可能认为,但是app常驻,同时又是系统进程,该app可能行为就和system server相同。

对这样的app,如果我们kill掉其进程,也会导致android重启,如同去杀掉了system server进程一样。

 

而在多用户下,带有system权限的app,如何启动在不同的进程呢?

其实只要app不具备android:persistent="true",就可达到该目的。

这样的app在启动后,在默认用户下,我们看到的进程用户为 system,但是在其他用户下,可能看到的用户就为u10_system。

 

<think>好的,用户之前已经询问过Android输入流程的梳理文档,现在他进一步要求更深入的源码分析。我需要先回顾一下之前的对话,确保这次的回答能够衔接上,并且满足他更深层次的需求。 首先,用户可能是一位Android开发者,或者是对系统底层感兴趣的学习者。他可能在开发过程中遇到了输入相关的问题,或者想深入理解机制以便优化应用。之前的回答已经覆盖了流程概览,现在他需要源码级别的分析,说明他希望了解具体实现细节,可能用于调试或自定义功能。 接下来,我需要确定用户的具体需求。是希望了解整个流程中各个模块的源码结构,还是某个特定部分的详细分析?比如InputReader、InputDispatcher,或者应用层的事件分发。根据他之前的问题,可能需要覆盖整个流程,但重点放在系统服务层和应用层的交互。 我需要整理源码分析的步骤,从系统服务层开始,包括InputManagerService、InputReader和InputDispatcher。这部分需要解释关键类的作用和交互流程,比如InputReader如何从设备读取事件,InputDispatcher如何分发事件。同时,要提到线程模型,比如InputReader和InputDispatcher运行在独立的线程中,使用EventHub监听设备节点。 然后,应用层方面,需要涉及InputChannel的注册过程,ViewRootImpl如何与WMS交互,以及事件如何传递到View树。这部分可能需要详细说明Binder通信和SocketPair的使用,以及事件在应用中的处理流程,比如通过InputEventReceiver接收事件,再分发到DecorView和Activity。 另外,用户可能对某些关键方法感兴趣,比如dispatchKeyEvent或onTouchEvent,需要指出这些方法在源码中的位置和调用链。同时,可以提到一些常见的Hook点,比如修改InputFilter来监控或修改事件,或者通过重写View的方法来改变事件处理逻辑。 还要考虑用户可能的进阶需求,比如如何调试输入事件,或者如何处理事件冲突。这时候需要推荐一些工具,如getevent、sendevent,或者adb命令来查看系统状态。此外,可以提到查看Android官方文档和源码中的测试用例,帮助用户进一步学习。 需要注意的是,源码分析可能会涉及复杂的代码结构,用户可能需要具体的代码路径和关键类的位置。因此,在回答中要提供清晰的代码路径,比如frameworks/base/services/core/java/com/android/server/input/,以及关键方法的签名和调用关系。 同时,用户可能对事件分发的细节,如ANR机制、焦点管理感兴趣,因此需要解释InputDispatcher如何检测应用响应超时,以及WMS如何维护焦点窗口。这部分内容需要结合源码中的超时处理和焦点更新逻辑。 最后,确保回答结构清晰,分模块讲解,并给出示例和调试方法,帮助用户将理论应用到实际开发中。可能还需要提醒用户注意线程和同步机制,避免在分析源码时产生混淆。</think>以下是对 Android 输入系统核心流程的 **源码级分析**,结合关键代码路径(基于 Android 13 源码)和核心逻辑: --- ### **1. 系统服务层源码分析** #### **1.1 InputManagerService 初始化** - **代码路径**: `frameworks/base/services/core/java/com/android/server/input/InputManagerService.java` `frameworks/native/services/inputflinger/InputManager.cpp` - **关键流程**: 1. **SystemServer 启动 InputManagerService**: ```java // SystemServer.java inputManager = new InputManagerService(context); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); ``` 2. **Native 层初始化**: 通过 JNI 调用 `NativeInputManager`,创建 `InputReader` 和 `InputDispatcher` 线程。 #### **1.2 InputReader 读取事件** - **代码路径**: `frameworks/native/services/inputflinger/InputReader.cpp` - **核心逻辑**: - **EventHub 监听设备节点**: ```cpp void EventHub::wake() { // 通过 epoll 监听 /dev/input 下的设备节点 struct epoll_event event; event.events = EPOLLIN; event.data.fd = mINotifyFd; epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mINotifyFd, &event); } ``` - **循环读取原始事件**: ```cpp void InputReader::loopOnce() { // 从 EventHub 获取原始事件(RawEvent) size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE); processEventsLocked(mEventBuffer, count); // 处理事件 } ``` - **事件转换**: 将 `RawEvent` 转换为 `KeyEvent` 或 `MotionEvent`(如 `processKey` 和 `processMotion` 方法)。 #### **1.3 InputDispatcher 分发事件** - **代码路径**: `frameworks/native/services/inputflinger/InputDispatcher.cpp` - **关键逻辑**: - **确定目标窗口**: ```cpp // 通过 WMS 查询窗口层级和焦点 sp<InputWindowHandle> windowHandle = findTouchedWindowAtLocked(displayId, x, y); ``` - **分发事件到 Socket**: ```cpp // 通过 InputChannel 发送事件到应用进程 status_t status = connection->inputPublisher.publishKeyEvent(...); ``` - **ANR 检测**: ```cpp // 超时未收到应用确认(5秒) nsecs_t timeout = connection->inputChannel->getTimeout(); if (currentTime > timeout) { onAnrLocked(connection); } ``` --- ### **2. 应用层源码分析** #### **2.1 InputChannel 注册** - **代码路径**: `frameworks/base/core/java/android/view/ViewRootImpl.java` - **流程**: - **窗口创建时注册 InputChannel**: ```java // ViewRootImpl.java mInputChannel = new InputChannel(); mWindowSession.addToDisplay(mWindow, ..., mInputChannel); ``` - **关联 InputEventReceiver**: ```java mInputEventReceiver = new WindowInputEventReceiver(mInputChannel, Looper.myLooper()); ``` #### **2.2 事件传递到 View 树** - **代码路径**: `frameworks/base/core/java/android/view/ViewRootImpl.java` `frameworks/base/core/java/android/view/View.java` - **关键方法**: 1. **InputEventReceiver.onInputEvent()**: ```java // ViewRootImpl.WindowInputEventReceiver public void onInputEvent(InputEvent event) { enqueueInputEvent(event, this, 0, true); } ``` 2. **ViewRootImpl.deliverInputEvent()**: 调用 `mView.dispatchPointerEvent(event)`(`mView` 是 `DecorView`)。 3. **Activity.dispatchTouchEvent()**: ```java // Activity.java public boolean dispatchTouchEvent(MotionEvent ev) { return getWindow().superDispatchTouchEvent(ev); } ``` 4. **ViewGroup.dispatchTouchEvent()**: 通过 `onInterceptTouchEvent` 决定是否拦截,最终调用子 `View` 的 `onTouchEvent`。 --- ### **3. 核心机制源码解析** #### **3.1 焦点窗口更新** - **代码路径**: `frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java` - **逻辑**: ```java // WMS 更新焦点窗口 void setFocusedWindowLocked(WindowState newFocus) { mCurrentFocus = newFocus; InputManagerService.updateFocusedWindow(newFocus); // 通知 InputDispatcher } ``` #### **3.2 事件拦截(ViewGroup)** - **代码路径**: `frameworks/base/core/java/android/view/ViewGroup.java` - **关键代码**: ```java public boolean dispatchTouchEvent(MotionEvent ev) { if (onInterceptTouchEvent(ev)) { // 检查是否拦截 // 拦截后转为自身处理 return super.dispatchTouchEvent(ev); } // 继续分发给子 View return child.dispatchTouchEvent(ev); } ``` --- ### **4. 调试与 Hook 技巧** #### **4.1 事件监控** - **InputFilter 拦截事件**: 实现 `InputFilter` 并注册到 `InputManagerService`,可修改或拦截全局输入事件。 - **代码路径**: `frameworks/base/core/java/android/view/IInputFilter.aidl` #### **4.2 关键日志** - **InputDispatcher 日志**: ```bash adb logcat -b events | grep "InputDispatcher" ``` - **View 事件日志**: 在 `View.dispatchTouchEvent` 中插入日志,观察事件传递路径。 --- ### **5. 流程图(源码视角)** ```plaintext 1. InputReader 线程: EventHub.read() → RawEvent → processEventsLocked() → KeyEvent/MotionEvent 2. InputDispatcher 线程: findTouchedWindowLocked() → publishKeyEvent() → Socket 发送 → App InputChannel 3. 应用进程: InputEventReceiver.onInputEvent() → ViewRootImpl → DecorView → Activity → View.dispatchTouchEvent() ``` --- ### **6. 深入建议** 1. **源码调试**: 使用 Android Studio 导入 `frameworks/base` 代码,断点调试 `InputDispatcher.cpp` 或 `ViewGroup.java`。 2. **官方文档**: 参考 [Android Input System Overview](https://source.android.com/docs/core/interaction/input)。 3. **实战案例**: 修改 `InputReader` 或 `InputDispatcher` 逻辑(如强制拦截返回键),需编译自定义 ROM。 如果需要分析特定模块(如多点触控或手势识别),可以进一步细化问题!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值