Android home和back事件处理
来源:互联网 发布:管家婆成本算法怎么改 编辑:程序博客网 时间:2024/06/06 20:52
本文基于Android 7.0
在Android系统中,back键事件是有app自己处理的,而home是系统全局处理事件,因为在任何app界面,按下home结果都是一样的回到launcher。
先看下back事件
back键处理
Android事件处理过程大致为
- Native层 –> ViewRootImpl层 –> DecorView层 –> Activity层 –> ViewGroup层 –> View层
frameworks/base/core/java/android/view/ViewRootImpl.javaprivate int processKeyEvent(QueuedInputEvent q) { final KeyEvent event = (KeyEvent)q.mEvent; // Deliver the key to the view hierarchy. if (mView.dispatchKeyEvent(event)) { return FINISH_HANDLED; } ... return FORWARD; }
这里的mView是DecorView,直接调用DecorView的dispatchKeyEvent分发事件
frameworks/base/core/java/com/android/internal/policy/DecorView.javapublic boolean dispatchKeyEvent(KeyEvent event) { ... if (!mWindow.isDestroyed()) { final Window.Callback cb = mWindow.getCallback(); final boolean handled = cb != null && mFeatureId < 0 ? cb.dispatchKeyEvent(event) : super.dispatchKeyEvent(event); if (handled) { return true; } } ... }
分发back事件时mWindow还玩destroy,因此会调用Callback的dispatchKeyEvent分发,这里Callback为Activity。
frameworks/base/core/java/android/app/Activity.javapublic boolean dispatchKeyEvent(KeyEvent event) { ... return event.dispatch(this, decor != null ? decor.getKeyDispatcherState() : null, this); }调用了KeyEvent的dispatch继续分发
frameworks/base/core/java/android/view/KeyEvent.javapublic final boolean dispatch(Callback receiver, DispatcherState state, Object target) { switch (mAction) { case ACTION_DOWN: { mFlags &= ~FLAG_START_TRACKING; if (DEBUG) Log.v(TAG, "Key down to " + target + " in " + state + ": " + this); boolean res = receiver.onKeyDown(mKeyCode, this); if (state != null) { if (res && mRepeatCount == 0 && (mFlags&FLAG_START_TRACKING) != 0) { if (DEBUG) Log.v(TAG, " Start tracking!"); state.startTracking(this, target); } else if (isLongPress() && state.isTracking(this)) { try { if (receiver.onKeyLongPress(mKeyCode, this)) { if (DEBUG) Log.v(TAG, " Clear from long press!"); state.performedLongPress(this); res = true; } } catch (AbstractMethodError e) { } } } return res; } case ACTION_UP: if (DEBUG) Log.v(TAG, "Key up to " + target + " in " + state + ": " + this); if (state != null) { state.handleUpEvent(this); } return receiver.onKeyUp(mKeyCode, this); case ACTION_MULTIPLE: final int count = mRepeatCount; final int code = mKeyCode; if (receiver.onKeyMultiple(code, count, this)) { return true; } if (code != KeyEvent.KEYCODE_UNKNOWN) { mAction = ACTION_DOWN; mRepeatCount = 0; boolean handled = receiver.onKeyDown(code, this); if (handled) { mAction = ACTION_UP; receiver.onKeyUp(code, this); } mAction = ACTION_MULTIPLE; mRepeatCount = count; return handled; } return false; } return false; }
主要看下ACTION_DOWN事件,这里receiver是activity。如果是长按,则会调用activity的onKeyLongPress
frameworks/base/core/java/android/app/Activity.javapublic boolean onKeyLongPress(int keyCode, KeyEvent event) { return false; }
可以看到直接返回false,忽略掉的长按事件
如果非长按,则会调用activity的onKeyDown
frameworks/base/core/java/android/app/Activity.java public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.ECLAIR) { event.startTracking(); } else { onBackPressed(); } return true; } ... } }
可以看到按下back键会调用onBackPressed()方法,该方法最终会调用到finish()方法。
frameworks/base/core/java/android/app/Activity.java public void onBackPressed() { if (mActionBar != null && mActionBar.collapseActionView()) { return; } if (!mFragments.getFragmentManager().popBackStackImmediate()) { finishAfterTransition(); } } public void finishAfterTransition() { if (!mActivityTransitionState.startExitBackTransition(this)) { finish(); } }
home事件
home事件是不经过app统一由系统处理的,在PhoneWindowManager端拦截掉了frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java// 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.public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) {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; ... handleShortPressOnHome(); return -1; }...}
private void handleShortPressOnHome() { // Turn on the connected TV and switch HDMI input if we're a HDMI playback device. getHdmiControl().turnOnTv(); // If there's a dream running then use home to escape the dream // but don't actually go home. if (mDreamManagerInternal != null && mDreamManagerInternal.isDreaming()) { mDreamManagerInternal.stopDream(false /*immediate*/); return; } // Go home! launchHomeFromHotKey(); }launchHomeFromHotKey就回到launcher了。
0 0
- Android home和back事件处理
- android处理Back键Home键和Menu键事件(转)
- android back/home 键事件
- Android手机Home键/Back回退键事件
- home键 和back键的处理
- android back和home键的捕获
- android back和home键的捕获
- Android home键和back键区别
- Android home键和back键区别
- Android home键和back键区别
- Android home键和back键区别
- Android home键和back键区别
- Android按Home键和Back键
- Android home键和back键区别
- Android home键和back键区别
- Android home键和back键区别
- android HOME、back(按钮、事件)截取获得,综合解决方案和分析,包含android4.0系统
- android HOME、back(按钮、事件)截取获得,综合解决方案和分析
- 【C】指针、引用和数组
- CodeForces-747B
- Spring4MVC+Spring4+Hibernate4整合系列--(二)StepByStep1
- Win32汇编--使用资源—版本信息资源
- Codeforces 491B
- Android home和back事件处理
- 程设作业 2016年12月23日15:52:33
- 从粉丝价值,看未来自媒体营销的市场“钱”景
- AArch64 是什么
- 军事仿真新纪元——全数据实时驱动视景仿真
- String方法调用面试题引发的思考
- 一般化规则
- 监控IIS并发连接数
- UILabel