SEO外包平台,我们为您提供专业的企业网站SEO整站优化外包服务 SEO设置

SEO外包平台

专注于企业网站SEO整站优化外包服务

Android事件传递分析-交付日志分析

作者:jcmp      发布时间:2021-05-19      浏览量:1
事件传递是Android系统中最基本的知
事件传递是Android系统中最基本的知识,但也是最繁琐、最复杂的知识,5.0以后传输变得更加复杂,互联网上有很多文章来分析事件分布,但从一开始,源代码中就有各种各样的解释,使得整个事件转移消费者事件的宏性不强。本文首先以最基本的日志来分析传输事件,如果您有耐心仔细分析这篇文章的话。我相信你知道一半的故事!稍后与源代码合作理解,我相信可以做得更好!

1.方法解释

2.定制组件

为了更好地解释交付和消费过程,我定义了两个容器和两个视图,分别是ViewGroupA、ViewGroupB、viewC、viewd,并重写了它们的onInterceptTouchEvent、DischTouchEvent、TouonchEvent。

代码如下:

公共类ViewGroupA扩展了LinearLayout{公共ViewGroupA(上下文){超级(上下文);}public ViewGroupA(上下文,AttributeSet Tatts){超(上下文,吸引);}public ViewGroupA(上下文上下文,AttributeSet Atatts,int DefStyleAttr){超级(上下文,Attribus,DefStyleAttr);}@覆盖公共布尔值onInterceptTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“onInterceptTouchEvent->”+ViewUtils.actionToString(ev.getAction();布尔结果=Super.onInterceptTouchEvent();Log.d(log_ID,this.getClass().geteName()+“onInterceptTouchEvent(EV)返回超级”;返回结果;返回结果;}@覆盖公共布尔DispatchTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent->”+ViewUtils.actionToString(ev.getAction();boboalResult=Super..DispatchTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent(EV)返回Super.DispatchTouchEvent(EV)”;返回结果;}@Suppress Lint(“ClickableViewAccesability”)@覆盖公共布尔值onTouchEvent(Motionent Event){Log.d(log_ID,this.getgetClass().SimpleName()+“onTouchEvent->”+Utils.ToString(Action();布尔结果=Super.onTouchent Event(EV);Log.d(log_ID,this.getClass().getSimpleName()+“onTouchEvent返回Super.onTouchEvent(EV)=”+Response);返回结果;}}

公共类ViewGroupB扩展LinearLayout{public ViewGroupB(上下文上下文){超级(上下文);}public ViewGroupB(上下文,AttributeSet Attributs){超级(上下文,吸引);}public ViewGroupB(上下文上下文,AttributeSet atts,int DefStyleAttr){Super(Context,atts,DefStyleAttr);}@Overoverpublic Boolean onInterceptTouchEvent(MotionEvent EV){log。D(log_ID,this.getClass().getSimpleName()+“onInterceptTouchEvent->”+ViewUtils.actionToString(ev.getAction();布尔结果=Super.onInterceptTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName()+“onIntercToueptchEvent返回Super.onInterceptchEvent(EV)=”+Result);返回结果;}@覆盖公共布尔DispatchTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent->”)+ViewUtils.actionToString(ev.getAction());布尔结果=Super.DispatchTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName())+DispatchTouchEvent(EV)返回Super.DispatchTouchEvent(EV);返回结果;}@覆盖公共布尔值onTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“onTouchEvent->”+ViewUtils.actionToString(ev.getAction();boole Resel=Super.onTouchEvent(EV);//boboeResue=true;Log.d(log_ID,此)。Getclass().getSimpleName()+“onTouchEvent返回Super.onTouchEvent(EV)=”+Response;返回结果;}

公共类ViewC扩展View{public ViewC(上下文上下文){Super(上下文);}public ViewC(上下文上下文,AttributeSet Attribus){超级(上下文,吸引);}public ViewC(上下文上下文,AttributeSet atts,int defStyleAttr){超级(上下文,Attribus,DefStyleAttr);}@覆盖公共布尔DispatchTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent->”)+ViewUtils.actionToString(ev.getAction());布尔结果=Super.DispatchTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName())+DispatchTouchEvent(EV)返回Super.DispatchTouchEvent(EV);返回结果;}@覆盖公共布尔值onTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName())+“onTouchEvent->”+ViewUtils.actionToString(EV)。GetAction());布尔结果=Super.onTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName()+“onTouchEvent返回Super.onTouchEvent(EV)=”+Result);返回结果;}}

公共类视图扩展View{public viewd(上下文){Super(上下文);}public viewd(上下文,AttributeSet吸引){超级(上下文,吸引);}public viewd(Context,AttributeSet atts,int DefStyleAttr){Super(Context,atts,DefStyleAttr);}@overoverpublic booleboalDispatchTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent->”+ViewUtils.ToactionString(ev.getAction(ev.getAction();布尔结果=Super.DispatchTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleName()+“DispatchTouchEvent返回Super.DispatchTouchEvent(EV)=”+Response“);返回结果;}@覆盖公用布尔值onTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass())。GetSimpleName()+“onTouchEvent->”+ViewUtils.actionToString(ev.getAction());布尔值结果=Super.onTouchEvent(EV);Log.d(log_ID,this.getClass().getSimpleEvent()+“onTouchEvent返回Super.onTouchEvent(EV)=”+Result);返回结果;}

工具方法:

公共类ViewUtils{公共静态最终操作_down=0;/*常量用于{@link#getActionMask}:一个按下的手势已经完成,*动作包含最后的发布位置以及自上次下降或移动事件以来的任何中间*点。*/public静态int action_up=1;/*常量用于{@link#getActionMask}:在*按下手势({@link#action_down}和{@link#action_up}之间)期间发生了更改。*议案载有最近的一点,以及自上一次下降或移动事件以来的任何中间点。*/public静态int action_move=2;/*用于{@link#getActionMask}的常量:当前手势已中止。*你不会再收到任何分数。您应该将其视为*UP事件,而不是执行任何您通常会执行的操作。*/public静态最终int action_Cancel=3;静态字符串actionToString(Int I){Switch(I){case 0:返回“action_down”;case 1:返回“action_up”;case 2:返回“action_move”;case 3:返回“action_Cancel”;默认值:返回“未知”;}}

<?xml版本=“1.0”编码=“utf-8”?>。视图组A>

图:

4,在完成上述布局后,日志分析

5,log

而不手动消耗事件

,我们什么都不做,直接点击控件日志如下:

D/点击事件:ViewGroupA DispatchTouchEvent->action_down D/点击事件:ViewGroupA onInterceptTouchEvent->action_down D/点击事件:ViewGroupA onInterceptTouchEvent返回。onInterceptTouchEvent(EV)=false D/点击事件:ViewGroupB DispatchTouchEvent->action_down D/点击事件:ViewGroupB onInterceptTouchEvent->action_down D/点击事件:ViewGroupB onInterceptTouchEvent返回超级。OnInterceptTouchEvent(EV)=false D/点击事件:ViewC DispatchTouchEvent->action_down D/点击事件:ViewC onTouchEvent->action_down D/点击事件:ViewC onTouchEvent(EV)=false D/点击事件:ViewC DispatchTouchEvent返回超级.DispatchTouchEvent(EV)=false D/点击事件:ViewGroupB onchEvent->action_down D/点击事件:ViewGroupB onTouchEvent返回超级点击事件:ViewGroupA onTouchEvent->action_down D/点击事件:ViewGroupA onTouchEvent返回Super.onTouchEvent(EV)=false D/点击事件:ViewGroupA DispatchTouchEvent返回Super.DispatchTouchEvent(EV)=false。在

单击viewC>之后,由于viewC和viewd位于同一个容器中,您单击的坐标区域不涉及viewd,因此日志中没有viewd信息(如下所示)。

6。在分析

之后,单击viewC:

7。手动消费事件不会手动拦截事件日志

,我们编写这样的代码

viewC。在密码里。

.OnClickListener{土司(“我正在消费此事件”)

也单击viewC以获得日志如下:

D/Click事件:ViewGroupA DispatchTouchEvent->action_down d/Click事件:ViewGroupA onInterceptTouchent->action_down d/Click事件:ViewGroupA onInterceptchEvchEvent返回Super.onInterceptTouchEvent(EV)=FalseD/事件:ViewB DispatchGrouchEvent->action_down d/Event:GroupB onIntercTouchent Evchent=FARSED/点击事件:ViewC DispatchTouchEvent->action_down d/点击事件:ViewC onTouchEvent->action_down d/点击事件:ViewC onTouchEvent返回Super.onTouchEvent(EV)=trued/点击事件:ViewC DispatchTouchEvent返回超级。DispatchTouchEvent(EV)=trued/点击事件:ViewGroupA DispatchTouchEvent返回Super.DispatchTouchEvent(EV)=trued/点击事件:ViewGroupA DispatchTouchEvent返回主管。DispatchTouchEvent(EV)=trued/点击事件:ViewGroupA DispatchTouchEvent->action_UPD/点击事件:ViewGroupA onInterceptTouchEvent->action_UPD/点击事件:ViewGroupA onInterceptTouchEvent返回Super.onInterceptTouchEvent(EV)=seD/点击事件:GroupB DispatchTouchEvent->action_upd/点击事件:ViewGroupentInterceptTouchEvent->点击事件/点击事件>_UPD/点击事件(EV)=FARSED/点击事件:ViewC DispatchTouchEvent->action_upd/点击事件:ViewC onTouchEvent->action_UPD/点击事件:ViewC onTouchEvent返回超级.onTouchEvent(EV)=trued/点击事件:ViewC DispatchTouchEvent返回超级.DispatchTouchEvent(EV)=trued/点击事件:ViewGroupB DispatchTouchEvent返回超级.DispatchTouchEvent(EV)=trued/点击事件:GroupA DispatchTouchEvent返回超级.DispatchTouchEvent(EV)=true。

8。在分析

时,您可以看到事件的传递与上面的相同。惟一的区别是viewC中的onTouchEvent()方法返回一个true,这一点也很明显。我们在前面添加了单击事件的处理。事实上,我们做了一个事件消耗。在使用此事件之后,DispatchTouchEvent()还返回一个true,通知他的父容器我已经使用了该事件,因为action_down事件是在这里处理的,因此需要以与action_down相同的方式处理action_up事件!

9。不要手动使用事件手动拦截事件的日志

我们进行拦截实验,我们在viewgroupB中修改onInterceptTouchEvent()的代码,我们手动返回一个true:

@覆盖InterceptTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass())上的公共布尔值。GetSimpleName()+“onInterceptTouchEvent->”+ViewUtils.actionToString(EV.)getAction();布尔结果=true;Log.d(log_ID,this.getClass().getSimpleName()+“onInterceptTouchEvent()+”onInterceptTouchEvent(EV)=“+Resue”);返回true;

同样点击viewC后得到日志如下:

D/点击事件:ViewGroupA DispatchTouchEvent->action_down d/点击事件:ViewGroupA onInterceptTouchEvent->action_down d/点击事件:ViewGroupA onInterceptTouchEvent返回超级。/点击事件:ViewGroupB onTouchEvent返回Super.onTouchEvent(EV)=FalseD/点击事件:ViewGroupB DispatchTouchEvent返回超级。DispatchTouchEvent(EV)=FARSED/点击事件:ViewGroupA onTouchEvent->action_down d/点击事件:ViewGroupA onTouchEvent返回Super.onTouchEvent(EV)=FalseD/点击事件:ViewGroupA DispatchTouchEvent返回Super.DispatchTouchEvent(EV)=false。

10。从直觉日志中分析

似乎只有视图A和视图B日志,是的。

11。手动消费事件日志

我们添加消费事件的代码:

viewGroupB.setOnClickListener{土司(“我消耗了此事件”)}

拦截事件并使viewGroupB的onInterceptTouchEvent返回为true。

公共布尔值onInterceptTouchEvent(MotionEvent EV){Log.d(log_ID,this.getClass().getSimpleName()+“onInterceptTouchEvent->”+ViewUtils.actionToString(ev.getAction();布尔结果=true;Log.d(log_ID,this.getClass().getSimpleName()+“onInterceptTouchEvent返回超级”。OnInterceptTouchEvent(EV)=“+Result”;返回true;}

此时我们单击viewC按钮日志如下:

D/Click事件:ViewGroupA DispatchTouchEvent->action_down d/Click Event:ViewGroupA onInterceptTouchEvent->action_down/Click Event:ViewGroupB onInterceptTouchEvent返回Super.onInterceptTouchEvent(EV)=FalseD/Click事件:ViewGroupB DispatchTouchEvent->action_down/Click:ViewGroupB onInterceptTouchEvent->action_down d/Click事件:ViewGroupB onIntercTouchEvent返回。OnTouchEvent返回Super.onTouchEvent(EV)=trued/点击事件:ViewGroupB DispatchTouchEvent返回超级。DispatchTouchEvent(EV)=trued/点击事件:ViewGroupA DispatchTouchEvent返回超级。DispatchTouchEvent(EV)=trued/点击事件:ViewGroupA DispatchTouchEvent->action_UPD/点击事件:ViewGroupA onInterceptTouchEvent->action_UPD/点击事件:ViewGroupA onInterceptTouchEvent返回超级。onInterceptTouchEvent(EV)=FalseD/点击事件:ViewGroupB DispatchTouchEvent->action_UPD/点击事件:ViewGroupB onTouchEvent->action_UPD/点击事件:ViewGroupB onTouchEvent返回超级表。

12,分析

当您到达这里时,您应该能够猜出将发生什么

13,总结

如果您认真阅读这里的日志,我相信您理解事件消耗的一半。至于为什么你没有看到当你点击,我们将继续分析它的源代码下一次!

14,提醒

需要源代码的朋友可以向邮箱imkobdroid@gmail.com发送请求,文章和代码有待改进!我希望我能沟通。