分析代码流程最可靠的方法是自己去加log、debug 代码。
-
网上是由一些好的文章,但有些受限于作者的水平,或者是作者看到的代码版本和我们看到的有差异,也可能会误导。
-
下面的堆栈是在Android 8.1版本上,分发ACTION_DOWN事件时,dispatchTouchEvent从ViewRootImpl开始,到view的dispatchTouchEvent 的流程。
"main@5554" prio=5 tid=0x2 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at android.widget.TextView.onTouchEvent(TextView.java:9714)
at android.view.View.dispatchTouchEvent(View.java:11809)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2600)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1830)
at android.app.Activity.dispatchTouchEvent(Activity.java:3321)
at android.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:53)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
at android.view.View.dispatchPointerEvent(View.java:12057)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4814)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4623)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4214)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4180)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4307)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4188)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4364)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4214)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4180)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4188)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4161)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6687)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6661)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6622)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6790)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:187)
at android.os.MessageQueue.nativePollOnce(MessageQueue.java:-1)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6521)
at java.lang.reflect.Method.invoke(Method.java:-1)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
从上面的堆栈简单的总结流程:
InputEventReceiver -> ViewRootImpl -> DecorView -> Activity -> PhoneWindow -> DecorView -> ViewGroup -> View
"main@10997" prio=5 tid=0x2 nid=NA runnable
java.lang.Thread.State: RUNNABLE
at android.widget.TextView.onDraw(TextView.java:6734)
at android.view.View.draw(View.java:19237)
at android.view.View.updateDisplayListIfDirty(View.java:18187)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4220)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4200)
at android.view.View.updateDisplayListIfDirty(View.java:18146)
at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:676)
at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:682)
at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:790)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:3006)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2810)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2363)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1396)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6778)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:967)
at android.view.Choreographer.doCallbacks(Choreographer.java:778)
at android.view.Choreographer.doFrame(Choreographer.java:713)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:953)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6521)
at java.lang.reflect.Method.invoke(Method.java:-1)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:536)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
button 的ondraw 流程如上所示。
未完,待续…