Input系统学习-----InputDispatcher中的looper

InputReader负责获取设备的输入数据,然后发给InputDispatcher去处理,为了让2个处理独立起来,不相互影响,它们是在不同的线程中执行的,

InputDispatcher里的threadLoop方法是继承的Thread的方法,会在一个while中不停的调用起来,

不停的调用,会不会太占用资源?

4623bool InputDispatcherThread::threadLoop() {
4624    mDispatcher->dispatchOnce();
4625    return true;
4626}

查看dispatchOnce方法,里面使用了  mLooper->pollOnce(timeoutMillis);来进行阻塞,就避免了不断的执行循环,

269void InputDispatcher::dispatchOnce() {
270    nsecs_t nextWakeupTime = LONG_LONG_MAX;
271    { // acquire lock
272        AutoMutex _l(mLock);
273        mDispatcherIsAliveCondition.broadcast();
274
275        // Run a dispatch loop if there are no pending commands.
276        // The dispatch loop might enqueue commands to run afterwards.
277        if (!haveCommandsLocked()) {
278            dispatchOnceInnerLocked(&nextWakeupTime);
279        }
280
281        // Run all pending commands if there are any.
282        // If any commands were run then force the next poll to wake up immediately.
283        if (runCommandsLockedInterruptible()) {
284            nextWakeupTime = LONG_LONG_MIN;
285        }
286    } // release lock
287
288    // Wait for callback or timeout or wake.  (make sure we round up, not down)
289    nsecs_t currentTime = now();
290    int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
291    mLooper->pollOnce(timeoutMillis);
292}

这里阻塞住了,我们可以猜想,InputReader传送数据过来的时候,就不再阻塞,

InputReader传送touch事件的时候,调用到InputDispatcher中的notifyMotion方法,

2527void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
2590        // Just enqueue a new motion event.
2591        MotionEntry* newEntry = new MotionEntry(args->eventTime,
2592                args->deviceId, args->source, policyFlags,
2593                args->action, args->actionButton, args->flags,
2594                args->metaState, args->buttonState,
2595                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
2596                args->displayId,
2597                args->pointerCount, args->pointerProperties, args->pointerCoords, 0, 0);
2598
2599        needWake = enqueueInboundEventLocked(newEntry);
2600        mLock.unlock();
2601    } // release lock
2602
2603    if (needWake) {
2604        mLooper->wake();
2605    }

可以看到。里面调用了  mLooper->wake();

就解除了dispatchOnce中的looper阻塞,在handler的相关调用中,Looper都隐藏的很深,几乎是透明的存在,看不到其身影,而这里,Looper现身了,不再隐藏,这里直接使用了其阻塞和唤醒功能来实现2个线程间的交互。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值