头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?

这篇具有很好参考价值的文章主要介绍了头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

我们可以看到,在 InputManager 里准备好了 mReader、mDispatcher,以及相关的两个线程,那么接下来当然就是把线程跑起来,好去读事件和分发事件。

启动事件读取和分发线程的调用链如下:

SystemServer.startOtherServices()
-> inputManagerService.start()
-> nativeStart() // com_android_server_input_InputManagerService.cpp
-> InputManager.start() // InputManager.cpp

最后的这个 start 方法很简单,就是把两个线程跑起来

status_t InputManager::start() {
status_t result = mDispatcherThread->run(“InputDispatcher”, PRIORITY_URGENT_DISPLAY);
result = mReaderThread->run(“InputReader”, PRIORITY_URGENT_DISPLAY);
}

至此,事件处理工作所需要的对象和线程都已经准备好了。前面那些代码看完记不住就算了,记住这句话:SystemServer 启动 IMS 时,会创建一个 native 的 InputManager 对象,这个 InputManager 会通过 mReader 不断读事件,再通过 mDispatcher 不断分发事件

接下来我们看下,事件是怎么读取和分发的。

事件的读取

InputReaderThread 等待按键消息到来,该 Thread 在 threadLoop 中无尽的调用 InputReader 的 loopOnce 方法。

bool InputReaderThread::threadLoop() {
mReader->loopOnce();
return true;
}

在 loopOnce 方法中会通过 EventHub 来获取事件,并放入 buffer 中:

void InputReader::loopOnce() {
// EventHub 从驱动读取事件
size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);

if (count) {
// 获取的事件是 RawEvent,需要处理成 KeyEvent、MotionEvent 等各种类型等
processEventsLocked(mEventBuffer, count);
}
// 将队列中事件刷给监听器,监听器实际上就是 InputDispatcher 事件分发器。
mQueuedListener->flush();
}

InputDispatcher 收到事件后调用,如果是 KeyEvent 会调用 notifyKey,如果是 MotionEvent 则会调用 notifyMotion

void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
KeyEvent event;
event.initialize(args->deviceId, args->source, args->action,
flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);

// 通过 NatvieInputManager 在 Event 入队前做一些处理
mPolicy->interceptKeyBeforeQueueing(&event, /byref/ policyFlags);


KeyEntry* newEntry = new KeyEntry(args->eventTime, args->source,
args->action, flags, keyCode,…)
// 事件放入队尾
needWake = enqueueInboundEventLocked(newEntry);
}

以上,便是 InputReader 获取到设备事件通知 InputDispatcher 并存放到事件队列中的流程。

事件的分发

下面将介绍 InputDispatcher 如何从事件队列中读取事件并分发出去。

首先在 InputDispatcherThread 的 threadLoop 中无尽的调用 dispatchOnce 方法

bool InputDispatcherThread::threadLoop() {
mDispatcher->dispatchOnce();
return true;
}

该方法两个功能:

  • 调用 dispatchOnceInnerLocked 分发事件;
  • 调用 runCommandsLockedInterruptible 来处理 CommandQueue 中的命令,出队并处理,直到队列为空。

void InputDispatcher::dispatchOnce() {
if (!haveCommandsLocked()) {
dispatchOnceInnerLocked(&nextWakeupTime);
}
if (runCommandsLockedInterruptible()) {
nextWakeupTime = LONG_LONG_MIN;
}

}

在 dispatchOnceInnerLocked 中会处理多种类型的事件,这里关注按键类型的(其他如触摸,设备重置等事件流程稍有区别)。一通调用后到 PhoneWindowManager , 终于回到 java 了,

InputDispatcher::dispatchOnceInnerLocked
-> dispatchKeyLocked
-> doInterceptKeyBeforeDispatchingLockedInterruptible
-> NativeInputManager.interceptKeyBeforeDispatching
-> PhoneWindowManager.interceptKeyBeforeDispatching

// 以下 NativeInputManager.doInterceptKeyBeforeDispatchingLockedInterruptible 的部分代码
nsecs_t delay = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputWindowHandle,
&event, entry->policyFlags);
if (delay < 0) {
// Home 事件将被拦截
entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_SKIP;
}
// 未被拦截的继续处理分发,本篇暂不分析

PhoneWindowManager

话不多说,继续看代码,离胜利不远了!源码的注释写得很清楚,我这边就不翻译了。真的不是因为懒,是想让你们提高点英语阅读水平 。(-> <-)

public long interceptKeyBeforeDispatching(KeyEvent event, …) {
// First we always handle the home key here, so applications
// can never break it, although if keyguard is on, we do let
// it handle it, because that gives us the correct 5 second
// timeout.
if (keyCode == KeyEvent.KEYCODE_HOME) {
// If we have released the home key, and didn’t do anything else
// while it was pressed, then it is time to go home!
if (!down) {
cancelPreloadRecentApps();
mHomePressed = false;

// Delay handling home if a double-tap is possible.
if (mDoubleTapOnHomeBehavior != DOUBLE_TAP_HOME_NOTHING) {
mHomeDoubleTapPending = true;
mHandler.postDelayed(mHomeDoubleTapTimeoutRunnable,
ViewConfiguration.getDoubleTapTimeout());
return -1;
}
handleShortPressOnHome(); //短按

//-1 调用处的事件结果就会赋值 INTERCEPT_KEY_RESULT_SKIP
return -1;
}

// Remember that home is pressed and handle special actions.
if (repeatCount == 0) {
mHomePressed = true;
if (mHomeDoubleTapPending) {
handleDoubleTapOnHome();//双击
} else if (mDoubleTapOnHomeBehavior == DOUBLE_TAP_HOME_RECENT_SYSTEM_UI) {
preloadRecentApps();//最近 app
}
} else if ((event.getFlags() & KeyEvent.FLAG_LONG_PRESS) != 0) {
if (!keyguardOn) {
handleLongPressOnHome(event.getDeviceId());//长按
}
}
return -1;
}
}

Home 的相关事件都在这处理啦。接下来我们就看一下 handleShortPressOnHome 短按 Home 进入 Luncher 是怎么实现的吧。

private void handleShortPressOnHome() {

// Go home! 坚持下,看完我们就 Go Home!
launchHomeFromHotKey();
}

Go Home!

void launchHomeFromHotKey(final boolean awakenFromDreams, final boolean respectKeyguard) {
if (respectKeyguard) {
// 处理一些锁屏的情况,可能直接 return
}
// no keyguard stuff to worry about, just launch home!
if (mRecentsVisible) {
// 延时后台的打开 Activity 的操作,避免打扰用户的操作
// 虽然方法名 stop 实际实现是延时 5s
ActivityManager.getService().stopAppSwitches();
// Hide Recents and notify it to launch Home
hideRecentApps(false, true);
} else {
// Otherwise, just launch Home
startDockOrHome(true /fromHomeKey/, awakenFromDreams);
}
}

最后看一下跳转到 Home 的一些细节

void startDockOrHome(boolean fromHomeKey, boolean awakenFromDreams) {
ActivityManager.getService().stopAppSwitches();
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?,程序员,android,智能手机,github
最后

想要了解更多关于大厂面试的同学可以点赞支持一下,除此之外,我也分享一些优质资源,包括:Android学习PDF+架构视频+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。文章来源地址https://www.toymoban.com/news/detail-847672.html

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

想要了解更多关于大厂面试的同学可以点赞支持一下,除此之外,我也分享一些优质资源,包括:Android学习PDF+架构视频+源码笔记高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 这几块的内容。非常适合近期有面试和想在技术道路上继续精进的朋友。

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

到了这里,关于头条Android高级开发岗二面:按下手机的-Home-键,有哪些动作和事件发生?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 手机的高级终端 Termux 安装、使用

     From:https://www.sqlsec.com/2018/05/termux.html Termux 高级终端安装使用配置教程 :https://www.cnblogs.com/cutesnow/p/11430833.html 神器Termux 的使用记录:https://cloud.tencent.com/developer/article/1609398 adb shell 下使用 termux:https://github.com/alwaystest/blog/issues/68 ttyd --- Share your terminal over the web:https://git

    2024年02月08日
    浏览(48)
  • VBA高级应用30例应用2:MouseMove鼠标左键按下并移动鼠标事件

    《VBA高级应用30例》(版权10178985),是我推出的第十套教程,教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开,这套教程案例与理论结合,紧贴“实战”,并做“战术总结”,以便大家能很好的应用。教程的目的是要求大家 在实际工作中分发VBA程序,写好的

    2024年04月27日
    浏览(37)
  • 3分钟了解Android中稳定性测试_手机稳定性测试,大厂软件测试高级多套面试专题整理集合

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新软件测试全套学习资料》

    2024年04月26日
    浏览(45)
  • Android架构进阶之高级UI系列(精编解析,值得收藏),Android开发面试技能介绍

    CallbackRecord callbacks; synchronized (mLock) { final long now = System.nanoTime(); // 根据指定的类型CallbackkQueue中查找到达执行时间的CallbackRecord callbacks = mCallbackQueues[callbackType].extractDueCallbacksLocked( now / TimeUtils.NANOS_PER_MS); if (callbacks == null) { return; } mCallbacksRunning = true; if (callbackType == Choreograph

    2024年04月13日
    浏览(42)
  • 手机移动开发技术,,Android开发经典实战

    面试题库 按照系统分类 按照大厂分类 《2017-2020字节跳动Android面试真题解析》 大神手写整理笔记类 《Android框架体系架构》 书籍类 不需要太多,精就好! 《第一行代码第二版》 技能提升资料库 一共十个专题,包括了Android进阶所有学习资料,Android进阶视频,Flutter,java基础

    2024年04月13日
    浏览(45)
  • Android Studio初学者实例:RecyclerView学习--模仿今日头条

    本案例来自于学校的一个简单的课程实验 先看效果图,可以显然的看到,一些item是不同的布局,而其他布局就是简单的布局嵌套 看一下xml代码:  XML代码中部分重复样式写入到了style文件中 看一下加入style.xm的代码,这个文件是存放在value文件夹下,存放样式、主题等。 看

    2024年02月06日
    浏览(62)
  • 安卓高级工程师面试题,Android 仪器化单元测试(1),ndk开发入门

    配置 build.gradle 依赖 dependencies { androidTestImplementation ‘androidx.test🏃1.4.0’ androidTestImplementation ‘androidx.test:rules:1.4.0’ } android { defaultConfig { testInstrumentationRunner “androidx.test.runner.AndroidJUnitRunner” } } 测试样例 测试代码 本例子参考 google 官方网站。因为官网里面很多类没有给到

    2024年04月16日
    浏览(43)
  • 8年老Android开发谈;高级UI都没弄明白凭什么拿高薪?

    Mithril.js 是一个精悍、短小的框架,使用它能使 React.js 的实现更整洁。在 Mithril 中,除了纯 JavaScript,你几乎能摆脱一切,同时,它还能让你在写布局的时候感受到图灵完备的语言所具备的力量。 return m(‘div’, m(‘p’, someText), m(‘ul’, items.map((item) = m(‘li’, item))), m(‘but

    2024年04月26日
    浏览(30)
  • android开发获取手机麦克风设备信息

    之前为了测试蓝牙耳机的麦克,想从蓝牙耳机的麦克录音。尝试发现三星、小米自带的录音机并不能从蓝牙录音。看了网上一篇文章,提供了一个特定的录音APP,才支持开启蓝牙录音功能。 非常令人疑惑。想到现在的手机,有不只一个麦克风,是否能开发一个可选择录音源的

    2024年04月16日
    浏览(44)
  • android开发:获取手机IP和UDP广播

            UDP广播在通讯双方互相不知道对方IP的情况下很有用。这种情形我们也可以用遍历网段来实现,但是比较粗暴,如果网段比较大,不是最多256台主机的C类网段的话,很难做遍历。         UDP广播是解决这种问题的标准方案。         注意,广播和多播是不同的,广

    2024年02月19日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包