andorid中dispatchkeyevent事件傳遞及焦點獲取

	DalvikVM[localhost:8601]	
		Thread [<1> main] (Suspended (breakpoint at line 740 in Workspace))	
			<VM does not provide monitor information>	
			Workspace.dispatchKeyEvent(KeyEvent) line: 740	
			FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246	
			FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246	
			FrameLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246	
			LinearLayout(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246	
			PhoneWindow$DecorView(ViewGroup).dispatchKeyEvent(KeyEvent) line: 1246	
			PhoneWindow$DecorView.superDispatchKeyEvent(KeyEvent) line: 1879	
			PhoneWindow.superDispatchKeyEvent(KeyEvent) line: 1361	
			Launcher(Activity).dispatchKeyEvent(KeyEvent) line: 2324	
			Launcher.dispatchKeyEvent(KeyEvent) line: 6542	
			PhoneWindow$DecorView.dispatchKeyEvent(KeyEvent) line: 1806	
			ViewRootImpl.deliverKeyEventPostIme(KeyEvent, boolean) line: 3327	
			ViewRootImpl.handleFinishedEvent(int, boolean) line: 3300	
			ViewRootImpl.handleMessage(Message) line: 2460	
			ViewRootImpl(Handler).dispatchMessage(Message) line: 99	
			Looper.loop() line: 137	
			ActivityThread.main(String[]) line: 4429	
			Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]	
			Method.invoke(Object, Object...) line: 511	
			ZygoteInit$MethodAndArgsCaller.run() line: 795	
			ZygoteInit.main(String[]) line: 562	
			NativeStart.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> [email protected]@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)	

從以上我們可以看到事件是通過頂層view往下傳遞的

再查看viewgroup源碼

    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;
    }
是從focused view往下傳遞事件


可以參考:

Android 中keyEvent的消息處理


再來按home鍵,從新獲取焦點的處理:

Home鍵
2.6_BesTVLauncherInside [Android Application]	
	DalvikVM[localhost:8601]	
		Thread [<1> main] (Suspended (breakpoint at line 50 in TintView$1))	
			<VM does not provide monitor information>	
			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: 5328	
			ViewRootImpl.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: 682	
			Workspace.snapToScreen(int, int, boolean) line: 1448	
			Workspace.snapToScreen(int) line: 1422	
			Workspace.scrollFirst() line: 1562	
			Launcher.onNewIntent(Intent) line: 1658	
			Instrumentation.callActivityOnNewIntent(Activity, Intent) line: 1123	
			ActivityThread.deliverNewIntents(ActivityThread$ActivityClientRecord, List) line: 2042	
			ActivityThread.performNewIntents(IBinder, List) line: 2055	
			ActivityThread.handleNewIntent(ActivityThread$NewIntentData) line: 2064	
			ActivityThread.access$1400(ActivityThread, ActivityThread$NewIntentData) line: 123	
			ActivityThread$H.handleMessage(Message) line: 1194	
			ActivityThread$H(Handler).dispatchMessage(Message) line: 99	
			Looper.loop() line: 137	
			ActivityThread.main(String[]) line: 4429	
			Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]	
			Method.invoke(Object, Object...) line: 511	
			ZygoteInit$MethodAndArgsCaller.run() line: 795	
			ZygoteInit.main(String[]) line: 562	
			NativeStart.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> [email protected]@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

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();
        }
    }
</pre><pre code_snippet_id="626730" snippet_file_name="blog_20150324_7_4283735" name="code" class="java"><span style="white-space:pre">		</span>
ViewRootImpl.clearChildFocus(View) line: 2200<span style="white-space:pre">	</span>
</pre>viewrootimpl中:<p></p><p></p><pre code_snippet_id="626730" snippet_file_name="blog_20150324_10_4665189" name="code" class="java">    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);
        }
    }


viewgroup中:

<pre name="code" class="java">    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;
    }



children[i]中的第一個節點最先獲取焦點





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章