Application of AOP in Android: Filtering Repeated Clicks

  • 2021-10-15 11:42:01
  • OfStack

Preface

Everyone should be familiar with AOP. Even if they have not used it, they must have heard of it. Section programming 1 is a hot topic. AOP is the abbreviation of Aspect Oriented Programming, which is used to be called section programming; Different from the idea of modularization of everything in OOP (Object-Oriented Programming), AOP manages a class of problems involving many modules in a unified way. The advantage of AOP is that it highly decouples business logic from systematic functions, so that we can only focus on business logic in the development process, and other systematic functions (such as routing, logging, authority control, interceptor, buried point, event anti-shake, etc.) are handled by AOP in a unified way;

Introduction to AspectJ

AOP is a programming idea or methodology, while AspectJ is a language specially designed for AOP, which supports native JAVA and can be used to deal with AOP related problems in java. The following is a very simple description of several key points in AspectJ

Join Points

The tangent point in AspectJ is the description of AspectJ acting on a specific position, which mainly includes three categories:

Function (function call, function execution, constructor, etc.) Variables (variable get, variable set, etc.) Code block (static code block, for, etc.)

Pointcuts

The section in AspectJ, from point to point, is used to explain which kind of problem you need hook. For example, I need all the life cycle methods of Activity in hook, then:


@Pointcut("execution(* android.app.Activity.on*(..))") 

advice

Join Points and Pointcuts are used to specify which locations or processes are required for hook, and advice is used to specify what needs to be done after hook, including:

before() Operate before the breakthrough point

after() Operate after the pointcut

after():returning Function ends normally after():throwing Function ends abnormally

around() Fully replace the function (you can call the original function manually)

around() It will be used more, because the degree of freedom is high, and others will be used around() Can be realized

AOP handles repeated clicks in android

Repeated clicks for a short period of time can bring bad experience and may cause problems if they are not handled (opening multiple pages, Multiple submissions, data disorder), I wrote an article before using proxy mode + reflection to deal with the problem of repeated clicks: Android-how to deal with repeated clicks gracefully, although this method can achieve the goal and is flexible, it is still invasive and not completely transparent to business logic, so we need to use a good way to deal with it;

AOP is used to deal with a certain type of independent problem, which is very suitable for shielding repeated clicks. We only need hook to live in the original click event (to be sure, it is the processing flow after the click event) and judge whether it is repeated clicks. If so, filter it out and prevent it from executing, otherwise it will be executed normally;

Code

To implement AspectJ in Android, it is recommended to use the framework of Hujiang, gradle_plugin_android_aspectjx, which can easily integrate and configure the environment of AspectJ in Android

Integration


//root gradle
 dependencies {
 classpath 'com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.1'
 }

//app Or module gradle
apply plugin: 'android-aspectjx' // Plug-ins 

compile 'org.aspectj:aspectjrt:1.8.9' //jar

AspectJ code


@Aspect
public class ClickFilterHook {
 private static Long sLastclick = 0L;
 private static final Long FILTER_TIMEM = 1000L;

 @Around("execution(* android.view.View.OnClickListener.onClick(..))")
 public void clickFilterHook(ProceedingJoinPoint joinPoint) {
 if (System.currentTimeMillis() - sLastclick >= FILTER_TIMEM) {
 sLastclick = System.currentTimeMillis();
 try {
 joinPoint.proceed();
 } catch (Throwable throwable) {
 throwable.printStackTrace();
 }
 } else {
 Log.e("ClickFilterHook", " Repeat clicking , Filtered ");
 }
 }
}

Test


 // Ordinary way  ok
 mBtn.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Toast.makeText(MainActivity.this," Effective click ",Toast.LENGTH_SHORT).show();
 }
 });


 //butterknife Etc IOC Framework  ok
 @OnClick({R.id.btn})
 public void onViewClicked(View view) {
 switch (view.getId()) {
 case R.id.btn:
 Toast.makeText(MainActivity.this," Effective click ",Toast.LENGTH_SHORT).show();
 break;
 }
 }

 // Customize view ok
 @BindView(R.id.tv_small_up)
 StrokeTextView mTvSmallUp;
 ...
 mTvSmallUp.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Toast.makeText(MainActivity.this," Effective click ",Toast.LENGTH_SHORT).show();
 }
 });

It can be found that when we deal with the code with repeated clicks, there is no coupling to the original code, and it is completely transparent to the business logic, even not reflected in the business logic code. This kind of problem has been dealt with well and is handled globally;

Say a few points in the above code:

1. @ Aspect: This annotation is used to mark the class that uses Aspect, that is, the class that you write Aspec code for

2. @ Around ("...")

3. The @ Around annotation is used to annotate the processing code after hook. We use Around here because the original function (onClick) may or may not be executed; The parameters in the annotation correspond to Pointcuts

"execution(* android.view.View.OnClickListener.onClick(..))" Corresponding to Pointcuts, use a similar regular expression to tell the controller which functions (methods) you need hook execution: It means that the process of hook is a function execution process (there are many kinds of Join and Points, and execution is only one of them. For details, please refer to the official document of AspectJ)
android.view.View.OnClickListener.onClick(..)) : Indicates android.view.View.OnClickListener All functions under this class (or interface) named onClick with unknown number of parameters and unknown parameter types

Summarize

We filter out the events of repeated clicks through the aspect-oriented idea, which is highly decoupled. We can see that the code is very simple. AOP focuses on understanding this idea and finding the right entry point; AOP can also have many applications in Android, such as:

Permission Control of Android API23 + Traceless burial point Global login process control Routing control Log system Event anti-shake (repeat click) ...

I will have the opportunity to talk about these applications later; If there is any incorrect or inappropriate description of the article, please make sure that I correct it in time, so as not to mislead more basin friends;

Reference: In-depth understanding of AOP of Android

Summarize


Related articles: