Dispatchkeyevent event transfer and focus acquisition in andorid
DalvikVM[localhost:8601]Thread [<1> main] (Suspended (breakpoint at line 740 in Workspace))
Workspace.dispatchKeyEvent(KeyEvent) line: 740FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246LinearLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246PhoneWindow$DecorView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246PhoneWindow$DecorView.superDispatchKeyEvent(KeyEvent) line: 1879PhoneWindow.superDispatchKeyEvent(KeyEvent) line: 1361Launcher(Activity).dispatchKeyEvent(KeyEvent) line: 2324Launcher.dispatchKeyEvent(KeyEvent) line: 6542PhoneWindow$DecorView.dispatchKeyEvent(KeyEvent) line: 1806ViewRootImpl.deliverKeyEventPostIme(KeyEvent, boolean) line: 3327ViewRootImpl.handleFinishedEvent(int, boolean) line: 3300ViewRootImpl.handleMessage(Message) line: 2460ViewRootImpl(Handler).dispatchMessage(Message) line: 99Looper.loop() line: 137ActivityThread.main(String[]) line: 4429Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]Method.invoke(Object, Object...) line: 511ZygoteInit$MethodAndArgsCaller.run() line: 795ZygoteInit.main(String[]) line: 562NativeStart.main(String[]) line: not available [native method]Thread [<10> Binder Thread #2] (Running)Thread [<9> Binder Thread #1] (Running)Daemon Thread [<8> FinalizerWatchdogDaemon] (Running)Daemon Thread [<7> FinalizerDaemon] (Running)Daemon Thread [<6> ReferenceQueueDaemon] (Running)Daemon Thread [<11> java.lang.ProcessManager] (Running)Thread [<12> launcher-loader] (Running)Thread [<13> launcher-loader] (Running)Thread [<15> Timer-1] (Running)Thread [<14> Timer-0] (Running)Thread [<18> SoundPool] (Running)Thread [<19> SoundPoolThread] (Running)Thread [<20> Thread-96] (Running)Thread [<21> DaemonThread] (Running)Thread [<17> SerialHandler] (Running)Daemon Thread [<22> RefQueueWorker@org.apache.http.impl.conn.tsccm.ConnPoolByRoute@4202f9a8] (Running)Thread [<25> Thread-104] (Running)Thread [<26> pool-2-thread-1] (Running)Thread [<28> pool-2-thread-2] (Running)Thread [<29> pool-2-thread-3] (Running)Thread [<30> pool-2-thread-4] (Running)Thread [<31> pool-2-thread-5] (Running)Thread [<32> pool-2-thread-6] (Running)Thread [<33> pool-2-thread-7] (Running)Thread [<34> pool-2-thread-8] (Running)Thread [<35> pool-2-thread-9] (Running)Thread [<36> pool-2-thread-10] (Running)Thread [<16> Binder Thread #3] (Running)Thread [<39> AsyncTask #5] (Running)Thread [<40> AsyncTask #6] (Running)Thread [<42> AsyncTask #8] (Running)Thread [<44> AsyncTask #10] (Running)Thread [<49> AsyncTask #15] (Running)Thread [<27> Thread-149] (Running)
From the above we can see that the event is passed down through the top-level view.
View the viewgroup source code.
public boolean dispatchKeyEvent(KeyEvent event) { if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onKeyEvent(event, 1); } if ((mPrivateFlags & (FOCUSED | HAS_BOUNDS)) == (FOCUSED | HAS_BOUNDS)) { if (super.dispatchKeyEvent(event)) { return true; } } else if (mFocused != null && (mFocused.mPrivateFlags & HAS_BOUNDS) == HAS_BOUNDS) { if (mFocused.dispatchKeyEvent(event)) { return true; } } if (mInputEventConsistencyVerifier != null) { mInputEventConsistencyVerifier.onUnhandledEvent(event, 1); } return false; }
The event is passed down from the focused view.
Refer:
KeyEvent Message Processing in Android
Press the home Key to obtain the focus again:
Home Key 2.6 _ BesTVLauncherInside [Android Application] DalvikVM [localhost: 8601] Thread [<1> main] (suincluded (breakpoint at line 50 in TintView $1 ))
TintView $1. onFocusChange (View, boolean) line: 50 FocusView (View ). onFocusChanged (boolean, int, Rect) line: 3863 FocusView (CusFocusView ). onFocusChanged (boolean, int, Rect) line: 205 FocusView (View ). handleFocusGainInternal (int, Rect) line: 3685 FocusView (View ). requestFocus (int, Rect) line: 5378 TintView (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 TintView (ViewGroup ). requestFocus (int, Rect) line: 2110 LinearLayout (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 LinearLayout (ViewGroup ). requestFocus (int, Rect) line: 2110 FrameLayout (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 FrameLayout (ViewGroup ). requestFocus (int, Rect) line: 2110 FrameLayout (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 FrameLayout (ViewGroup ). requestFocus (int, Rect) line: 2110 FrameLayout (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 FrameLayout (ViewGroup ). requestFocus (int, Rect) line: 2110 LinearLayout (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 LinearLayout (ViewGroup ). requestFocus (int, Rect) line: 2110 PhoneWindow $ DecorView (ViewGroup ). onRequestFocusInDescendants (int, Rect) line: 2154 PhoneWindow $ DecorView (ViewGroup ). requestFocus (int, Rect) line: 2113 PhoneWindow $ DecorView (View ). requestFocus (int) line: 5328ViewRootImpl. clearChildFocus (View) line: 2200 PhoneWindow $ DecorView (ViewGroup ). clearChildFocus (View) line: 669 LinearLayout (ViewGroup ). clearChildFocus (View) line: 669 FrameLayout (ViewGroup ). clearChildFocus (View) line: 669 FrameLayout (ViewGroup ). clearChildFocus (View) line: 669 FrameLayout (ViewGroup ). clearChildFocus (View) line: 669 Workspace (ViewGroup ). clearChildFocus (View) line: 669 ChildLayout (ViewGroup ). clearChildFocus (View) line: 669 CellLayout (ViewGroup ). clearChildFocus (View) line: 669 FrameView (ViewGroup ). clearChildFocus (View) line: 669 FrameLayout (ViewGroup ). clearChildFocus (View) line: 669 FocusView (View ). clearFocus () line: 3756 FrameLayout (ViewGroup ). clearFocus () line: 682 FrameView (ViewGroup ). clearFocus () line: 682 CellLayout (ViewGroup ). clearFocus () line: 682 ChildLayout (ViewGroup ). clearFocus () line: 682Workspace. snapToScreen (int, int, boolean) line: 1448Workspace. snapToScreen (int) line: 1422Workspace. scrollFirst () line: 1562Launcher. onNewIntent (Intent) line: 1658Instrumentation. callActivityOnNewIntent (Activity, Intent) line: 1123ActivityThread. deliverNewIntents (ActivityThread $ ActivityClientRecord, List) line: 2042ActivityThread. extends mnewintents (IBinder, List) line: 2055ActivityThread. handleNewIntent (ActivityThread $ NewIntentData) line: 2064ActivityThread. access $1400 (ActivityThread, ActivityThread $ NewIntentData) line: 123 ActivityThread $ H. handleMessage (Message) line: 1194 ActivityThread $ H (Handler ). dispatchMessage (Message) line: 99Looper. loop () line: 137ActivityThread. main (String []) line: 4429Method. invokeNative (Object, Object [], Class, Class [], Class, int, boolean) line: not available [native method] Method. invoke (Object, Object ...) line: 511 ZygoteInit $ MethodAndArgsCaller. run () line: 795ZygoteInit. main (String []) line: 562NativeStart. main (String []) line: not available [native method] Thread [<10> Binder Thread #2] (Running) Thread [<9> Binder Thread #1] (Running) daemon Thread [<8> FinalizerWatchdogDaemon] (Running) Daemon Thread [<7> FinalizerDaemon] (Running) Daemon Thread [<6> ReferenceQueueDaemon] (Running) daemon Thread [<11> java. lang. processManager] (Running) Thread [<12> launcher-loader] (Running) Thread [<13> launcher-loader] (Running) thread [<15> Timer-1] (Running) Thread [<14> Timer-0] (Running) Thread [<18> SoundPool] (Running) thread [<19> SoundPoolThread] (Running) Thread [<20> Thread-96] (Running) Thread [<21> DaemonThread] (Running) thread [<17> SerialHandler] (Running) Daemon Thread [<22> RefQueueWorker@org.apache.http.impl.conn.tsccm.ConnPoolByRoute @ 4202f9a8] (Running) Thread [<25> Thread-104] (Running) thread [<26> pool-2-thread-1] (Running) Thread [<28> pool-2-thread-2] (Running) thread [<29> pool-2-thread-3] (Running) Thread [<30> pool-2-thread-4] (Running) thread [<31> pool-2-thread-5] (Running) Thread [<32> pool-2-thread-6] (Running) thread [<33> pool-2-thread-7] (Running) Thread [<34> pool-2-thread-8] (Running) thread [<35> pool-2-thread-9] (Running) Thread [<36> pool-2-thread-10] (Running) thread [<16> Binder Thread #3] (Running) Thread [<39> AsyncTask #5] (Running) Thread [<40> AsyncTask #6] (Running) thread [<42> AsyncTask #8] (Running) Thread [<44> AsyncTask #10] (Running) Thread [<49> AsyncTask #15] (Running)
ChildLayout (ViewGroup). clearFocus () line: 682
Workspace. snapToScreen (int, int, boolean) line: 1448
Clearfocus is called.
In viewgroup:
/** * {@inheritDoc} */ @Override public void clearFocus() { super.clearFocus(); // clear any child focus if it exists if (mFocused != null) { mFocused.clearFocus(); } }
View:
public void clearFocus() { if (DBG) { System.out.println(this + " clearFocus()"); } if ((mPrivateFlags & FOCUSED) != 0) { mPrivateFlags &= ~FOCUSED; if (mParent != null) { mParent.clearChildFocus(this); } onFocusChanged(false, 0, null); refreshDrawableState(); } }
ViewRootImpl.clearChildFocus(View) line: 2200
In viewrootimpl:
public void clearChildFocus(View child) { checkThread(); View oldFocus = mFocusedView; if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Clearing child focus"); mFocusedView = mRealFocusedView = null; if (mView != null && !mView.hasFocus()) { // If a view gets the focus, the listener will be invoked from requestChildFocus() if (!mView.requestFocus(View.FOCUS_FORWARD)) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); } } else if (oldFocus != null) { mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(oldFocus, null); } }
In viewgroup:
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { int index; int increment; int end; int count = mChildrenCount; if ((direction & FOCUS_FORWARD) != 0) { index = 0; increment = 1; end = count; } else { index = count - 1; increment = -1; end = -1; } final View[] children = mChildren; for (int i = index; i != end; i += increment) { View child = children[i]; if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { if (child.requestFocus(direction, previouslyFocusedRect)) { return true; } } } return false; }
The first node in children [I] obtains the focus first.