InputManagerService分析(一)

1, IMS启动

IMS(InputManagerService)管理android系统中的所有输入,包括常见的触摸屏和键盘,还包括各种传感器的输入。

IMS和其他的系统服务一样,都是在SystemServer中创建的,

inputManager = new InputManagerService(context);
static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = 
            android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore); ServiceManager.addService(Context.WINDOW_SERVICE, wm); ServiceManager.addService(Context.INPUT_SERVICE, inputManager); mActivityManagerService.setWindowManager(wm);inputManager.setWindowManagerCallbacks(wm.getInputMonitor());inputManager.start();

IMS和WMS千丝万缕的联系暂且不管,先看IMS的构造方法,

public InputManagerService(Context context) {
    this.mContext = context;
    this.mHandler = new InputManagerHandler(DisplayThread.get().getLooper());

    mUseDevInputEventForAudioJack =context.getResources().getBoolean(
              R.bool.config_useDevInputEventForAudioJack);
   mPtr = nativeInit(this, mContext, mHandler.getLooper().getQueue());
  LocalServices.addService(InputManagerInternal.class, new LocalService());
    }

在构造函数中,构造了一个InputManagerHandler对象,看都不看就知道它的主要作用是将JNI层的调用切换到主线程中执行。

IMS对应的C/C++ 层为com_android_server_input_InputManagerService.cpp

nativeInit方法的具体代码如下:

static jlong nativeInit(JNIEnv* env, jclass /* clazz */,
        jobject serviceObj, jobject contextObj, jobject messageQueueObj) {
    sp<MessageQueue> messageQueue = 
            android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
        return 0;
    }

    NativeInputManager* im = new NativeInputManager(contextObj, serviceObj,
            messageQueue->getLooper());
    im->incStrong(0);
    return reinterpret_cast<jlong>(im);
}

由此可见, int 型变量mPtr保存的是NativeInputManager对象指针的地址。

看看NativeInputManager的构造函数,

NativeInputManager::NativeInputManager(jobject contextObj,
        jobject serviceObj, const sp<Looper>& looper) :
        mLooper(looper), mInteractive(true) {
    JNIEnv* env = jniEnv();

    mContextObj = env->NewGlobalRef(contextObj);
    mServiceObj = env->NewGlobalRef(serviceObj);

    {
        AutoMutex _l(mLock);
        mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
        mLocked.pointerSpeed = 0;
        mLocked.pointerGesturesEnabled = true;
        mLocked.showTouches = false;
    }
    mInteractive = true;

    sp<EventHub> eventHub = new EventHub();
    mInputManager = new InputManager(eventHub, this, this);
}

EventHub下个小节再论述,首先InputManager的构造方法,

InputManager::InputManager(
        const sp<EventHubInterface>& eventHub,
        const sp<InputReaderPolicyInterface>& readerPolicy,
        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
    mDispatcher = new InputDispatcher(dispatcherPolicy);
    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
    initialize();
}

照例又是新创建了两个对象, InputDispatcher, InputReader

void InputManager::initialize() {
    mReaderThread = new InputReaderThread(mReader);
    mDispatcherThread = new InputDispatcherThread(mDispatcher);
}

Initialize方法新建了2个线程对象。

接下来看看InputManagerService 的start方法,

static void nativeStart(JNIEnv* env, jclass /* clazz */, jlong ptr) {
    NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);

    status_t result = im->getInputManager()->start();
    if (result) {
        jniThrowRuntimeException(env, "Input manager could not be started.");
    }
}

getInputManager得到的是InputManager对象,

status_t InputManager::start() {
    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
    if (result) {
        ALOGE("Could not start InputDispatcher thread due to error %d.", result);
        return result;
    }

    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
    if (result) {
        ALOGE("Could not start InputReader thread due to error %d.", result);

        mDispatcherThread->requestExit();
        return result;
    }

    return OK;
}

终于让这2个线程跑起来了。

总体的流程图如下:


绕来绕去绕了这么久,结构图如下,


1,首先, InputManagerService创建一个NativeInputManager对象,

2,NativeInputManager创建EventHub, InputManager对象,

3,InputManager创建InputReader, InputDispatcher个对象和

InputReaderThread, InputDispatcherThread2个线程,

4,最后运行InputReaderThread, InputDispatcherThread程2个线程。

InputReaderThread是InputReader的内部类,负责各种事件的读取,相对应的, InputDispatcherThread是

那么, EventHub是做啥的呢?请看下篇文章。

### 三、Android 设备死机问题的分析与排查方法 Android 设备在运行过程中可能出现系统卡顿、无响应甚至完全死机的情况。这类问题通常涉及系统服务、内核、硬件驱动或第三方应用等多个层面。分析和排查这些问题需要结合日志、系统状态和调试工具。 #### 1. **系统服务异常** System Server 中运行着多个关键服务,如 ActivityManagerService、WindowManagerService、InputManagerService 等,任何个服务崩溃或卡死都可能导致系统无响应。例如,AMS 负责管理应用生命周期,若其出现死锁或资源占用过高,可能导致整个系统无法切换应用或响应用户操作[^3]。 - **日志分析**:通过 `logcat` 查看系统日志,关注 `ActivityManager`、`WindowManager`、`InputDispatcher` 等关键模块的异常信息。 - **Watchdog 机制**:系统内置 Watchdog 服务,若检测到关键服务无响应超过定时间(通常为 60 秒),会触发 ANR(Application Not Responding)并可能重启系统服务或设备。 #### 2. **内核问题** Linux 内核负责调度进程、管理内存、处理中断等关键任务。若内核存在死锁、内存泄漏或硬件驱动问题,可能导致系统完全死机。 - **内核日志(dmesg)**:通过 `dmesg` 命令获取内核日志,检查是否有 OOM(Out of Memory)、死锁、硬件中断异常等信息。 - **PMC 日志**:在某些平台上,可通过 PMC(Power Management Controller)日志分析电源管理相关问题,如系统在休眠或唤醒过程中卡死[^2]。 #### 3. **硬件驱动问题** 某些硬件驱动(如 GPU、Wi-Fi、蓝牙)若存在兼容性问题或资源占用异常,也可能导致系统冻结。 - **GPU 渲染问题**:查看 `SurfaceFlinger` 和 `HWComposer` 相关日志,确认是否因图形渲染阻塞导致界面无响应。 - **硬件中断异常**:检查 `/proc/interrupts` 文件,观察是否有中断风暴或中断未响应的情况。 #### 4. **内存与资源耗尽** 当系统内存(RAM)或 CPU 资源被大量占用时,可能导致系统调度失败,出现死机现象。 - **内存使用情况**:使用 `top`、`procrank`、`dumpsys meminfo` 等命令查看内存使用情况,识别内存泄漏或高内存占用进程。 - **CPU 使用率**:通过 `top -t` 或 `perf` 工具分析 CPU 使用情况,识别占用 CPU 时间过长的线程或进程。 #### 5. **第三方应用影响** 某些第三方应用可能存在内存泄漏、主线程阻塞或调用系统 API 不当,导致系统整体无响应。 - **安全模式排查**:进入安全模式(Safe Mode)禁用所有第三方应用,观察系统是否恢复正常。 - **ANR 日志分析**:检查 `/data/anr/` 目录下的 ANR 日志文件,分析主线程是否被阻塞。 #### 6. **系统更新与固件问题** 系统 OTA 更新过程中若出现中断或更新包不完整,可能导致系统服务异常或启动失败。 - **系统完整性检查**:使用 `adb shell getprop ro.build.fingerprint` 检查当前系统指纹是否与官方版本致。 - **恢复出厂设置**:若问题持续存在,可尝试恢复出厂设置以排除系统数据损坏。 #### 7. **调试与工具支持** - **ADB 调试**:通过 `adb logcat`、`adb bugreport` 获取完整系统日志。 - **Systrace 分析**:使用 `systrace` 工具追踪系统调度、UI 渲染、Binder 调用等关键路径,识别性能瓶颈。 - **Kernel Shark**:用于分析 ftrace 日志,识别内核调度问题。 ### 示例:查看 ANR 日志 ```bash adb pull /data/anr/traces.txt ``` ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值