您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

Android |使用AspectJ限制按钮快速点击。 《影视源码》

  • 时间:2022-09-09 11:04 编辑: 来源: 阅读:299
  • 扫一扫,手机访问
摘要:Android |使用AspectJ限制按钮快速点击。 《影视源码》
作者:彭丑丑转载:前言在Android开发中,限制按钮的快速点击(按钮防抖)是一个普遍的要求;在本文中,我将详细介绍一种使用AspectJ的方法,该方法基于注释解算器&运行时注释反射的原理 如果可以帮忙,请一定要赞,一定要关注,这对我真的很重要。 1.定义需求在解释开始之前,我们先定义需求,具体描述如下:限制快速点击需求表明意图:2。常规解决方案限制快速点击常见的解决方案有两种,如下:2.1封装代理类封装一个代理类来解决点击事件,代理类通过判断点击间隔来决定是否可以屏蔽点击事件。具体代码如下://agent类公共抽象类快速点击监听器implementsview.onclick监听器{ private longmlast clicktime私长区间= 1000Lpublic fastclick listener(){ } public fastclick listener(长间隔){ this.interval = interval} @ Override public void onClick(View v){ long current time = system . current time millis();if(current time-mLastClickTime & gt;Interval) {//经过了足够长的时间,允许单击onClick();mLastClickTime = nowTime} }受保护的抽象void onClick();}在需要限制快速点击的地方使用这个代理类,如下:TV . setonclicklistener(newfastcliclistener(){ @ override protected void onclick(){//solve click logic } });2.2 RxAndroid过滤表达式throttleFirst,RxJava的一个过滤表达式,也可以限制快速点击,如下:RX view。点击次数(视图)。Throttlefirst (1,时间单位。秒)。订阅(新消费者 我们需要一个解决方案来避免这两个缺点——AspectJ。 AspectJ是一个流行的Java AOP(面向方面编程)编程扩展框架。如果还不明白,请查看文章:《Android |带你穿越AspectJ框架》。3.详细步骤。在下面的内容中,我们将使用AspectJ框架,以限制快速点击的逻辑为核心关注点,并将其从业务逻辑中分离出来进行独立维护。 具体步骤如下:第一步:在依赖Hujiang的AspectJXGradle插件中添加AspectJ依赖项-在项目build.gradle://项目级build . gradledependencies { class path ' com . Android . tools . build:gradle:3 . 5 . 3 ' class path ' com . Hujiang . AspectJX:gradle-Android-plugin-AspectJX:2 .0.8'}如果插件下载速度太慢,可以直接依靠插件jar文件将插件下载到项目根目录(如/plugins)。然后在项目build . gradle://项目级build . gradledependencies { class path ' com . Android . tools . build:gradle:3 . 5 . 3 ' class path file tree(dir:' plugins ',Include:['*。jar'])}应用插件-在应用模块的build.gradle中应用插件://应用的build.gradleap插件:' Android-AspectJX '...依赖于AspectJ框架-在包含AspectJ代码的模块的build.gradle文件中添加依赖项://Level Module build . gradledependencies {...API '组织。AspectJ: AspectJ RT: 1.8.9 '...}第二步:实现判断快速点击的工具类。我们先实现一个判断视图是否可以快速点击的工具类;实现原理是利用View的tag属性存储上次点击时间,每次点击从存储的时间判断当前时间是否过去了足够长的时间;为了避免调用View#setTag(int key,Object tag)时传入的键与其他地方传入的键冲突,需要使用资源文件中定义的id,这样可以有效保证全局唯一性,如下://ids . XML < resources & gt;& ltitem type = " id " name = " view _ click _ time "/& gt;& lt/resources & gt;Classfastclickcheckkutil {/* * *确定是否可以快速点击* * @ param View clicked View * @ param interval快速点击阈值* @ return true:quick click */public static boolean is fast click(@ nonnull View View,long interval){ int key = r . id . View _ click _ time;//最新点击时间longcurrentclicktime = system . currenttimemillis();if(null = = view . gettag(key)){//1 \第一次点击//保存最后一次点击时间view.settag (key,当前点击时间);返回false} // 2\.不是第一次点击//最后一次点击时间longlastclicktime =(long)view . gettag(key);if(currentClickTime-last clicktime & lt;Interval){ //如果时间间隔没有超过,则视为快速点击返回true}else{ //保存上次点击时间view.settag (key,current clicktime);返回false}}}第三步:定义方面。使用@Aspect注释定义一个方面。用这个注释修饰的类会被AspectJ编译器识别为切面类:@ AspectPublic类fastclickcheckerphase {//然后填充}第四步:定义切入点切入点切入点切入点。用@Pointcut注释定义一个切入点切入点。在编译时,AspectJ编译器会搜索所有匹配的JoinPoint,执行编织:@ aspect公共类fast click aspect {//定义一个切入点:View。OnClickListener#onClick()方法@ pointcut(" execution(void Android . view . view . onClick listener . onClick(..))")public void methodviewonclick(){ }//然后填写Advice}第五步:定义建议强化的方法有很多种。这里我们使用@Around注释来定义环绕强化,它将包装切入点,并在切入点前后添加横切逻辑。如下:@ Aspect公共类fast click Aspect {//定义入口点:View。OnClickListener#onClick()方法@ pointcut(" execution(void Android . view . view . onClick listener . onClick(..))")public void methodViewOnClick(){ }//定义环绕增强,Wrap methodViewOnClick()pointcut @ around(" methodViewOnClick()")public void aroundviewonclick(前进连接点连接点)throwable {//取出目标对象view target =(view)join point . get args()[0];//根据点击间隔是否能超过2000,判断是否可以是快速点击if(!fastclickcheckutil . isfastclick(target,2000)){ join point . proceed();}}}第六步:实现视图。OnClickListener在这一步,我们为视图设置OnClickListener。我们可以看到并没有增加限制快速点击的相关代码,强化的逻辑并没有侵犯原有的逻辑。具体代码如下://源代码:公共类主活动扩展app compatibility { @ Override Protected Void Once(Bundle SavedInstanceState){ Super。一次(SavedInstanceState);setContentView(r . layout . activity _ main);findViewById(R.id.text)。setOnClickListener(新视图。onClick listener(){ @ Override public void onClick(View v){ log . I(" AspectJ "," click ");} });}}编译代码,然后反编译AspectJ编译器执行织好的。类文件。 我还是不明白怎么找编译的。类文件,一定要查看文章:《Android |带你穿越AspectJ框架》,公共类主活动扩展{ protected void once(bundle saved state){ super。一次(保存状态);setContentView(2131361820);findViewById(2131165349)。setOnClickListener(新视图。OnClickListener() {私有静态最终连接点。static part AJC $ tjp _ 0;//查看。onClick listener # onClick()public void onClick(View v){ View View = v;//重构JoinPoint,进行环绕增强,还执行@ Around join point join point = factory . makejp(AJC $ tJP _ 0,this,this,view)修改的方法;onClick _ around body 1 $ advice(this,view,joinPoint,FastClickAspect.aspectOf(),(ProceedingJoinPoint)join point);} static { AJC $ prec init();} private static void AJC $ prec init(){ Factory Factory = new Factory(" main activity . Java ",null . class);AJC $ tjp _ 0 = factory . makes jp(" method-execution ",(Signature)factory . make method SIG(" 1 "," onClick "," com . have . a . good . time . AspectJ . main activity $ 1 "," android.view.View "," v "," void "),25);}//查看原始代码。OnClickListener#onClick()相当于核心业务逻辑private static final void onClick _ around body 0(null AJC $ this,view v,join point param 1 join point){ log . I(" AspectJ "," click ");} // @Around方法代码,即源代码中的aroundViewOnClick(),相当于advice private static final void onclick _ aroundbody 1 $ advice(null AJC $ this,View v,JoinPoint thisJoinPoint,fastclickeaspect AJC $ aspect instance,ProceedingJoinPoint join point){ View target =(View)join point . get args()[0];如果(!Tclickcheckutil。isfast click (target,2000)){//对于非快速点击,执行点击逻辑:进行连接点进行连接点=连接点;onClick_aroundBody0(ajc$this,v,(join point)proceedingJoinPoint);null} } });}}总结这里我们来解释一下使用AspectJ框架限制按钮快速点击的细节。总结如下:用@Aspect注释描述一个facet,用这个注释修饰的类会被AspectJ编译器识别为facet类;使用@Pointcut注释来定义一个切入点。在编译时,AspectJ编译器将搜索所有匹配的连接点并执行编织。使用@Around注释来定义一个加强,它将被编织到匹配的连接点4中。进化现在,我们回到文章开头定义的需求,一共4点。 前两点在目前的方案中已经可以实现。现在我们重点关注后两点,即允许自定义时间间隔,覆盖尽可能多的点击场景。 需求回归表明意图:4.1在实际项目的不同场景下定制带时间间隔的按钮,往往需要限制不同的点击时间间隔,所以我们需要一种简单的方式来定制不同场景的时间间隔,或者对于少部分不需要限制快速点击的地方,有办法跳过快速点击判断。具体方法如下:定义comments/* * *并添加@FastClick comment */@ retention(保留策略。运行时)@ target (elementtype。方法),其中需要定制时间间隔。public @ interface fast click { long interval()default fast click aspect。快速_点击_间隔_全局;}修改切面类的advice @ Aspect公共类singleclicaspect { Public static final long fast _ click _ interval _ global = 1000 l;@ Pointcut(" execution(void Android . view . view . onclick listener . onclick(..))")public Void methodViewOnClick(){ } @ Around(" methodViewOnClick()")Void AroundViewOnClick(前进关节点关节点)Throwable {//取出关节点的签名method signature =(method signature)join point . get signature();//取出连接点的方法method method = method signature . get method();// 1\.全球统一时间间隔长间隔= fast _ click _ interval _ globalif(method . isanotationpresent(fast click . class)){//2 \如果用@FastClick修饰方法,则取出自定义的时间间隔fast click single click = method . get annotation(fast click . class);interval = single click . interval();}//取出目标对象view target =(view)join point . get args()[0];// 3\.根据点击间隔是否可以超过间隔,判断是否可以快速点击if(!fastclickcheckutil . isfastclick(target,interval)){ join point . proceed();}}}使用注释FindviewBoyd (r.id.text)。setonclicklistener(new View . onClick listener(){ @ fast click(interval = 5000 l)@ Override public void onClick(View v){ log . I(" AspectJ "," click ");}});4.2完整场景覆盖butter knife @ onclick Android:onclick ok回收器视图/listview Java lambda no kotlin lambda ok数据绑定ok编辑...如果你喜欢这篇文章,请给我点个赞,在评论区留言或者转帖支持~点击【GitHub】还有彩蛋!!!


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)
【技术支持|常见问题】别告诉我你没看过邰方这两则有思想的创意广告! (2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部