woong's

Android AOP를 이용한 중복 클릭 방지하기 본문

Develop/Android

Android AOP를 이용한 중복 클릭 방지하기

dlsdnd345 2017. 7. 20. 12:43

Android AOP를 이용한 중복 클릭 방지하기


Android 개발을 하다보면 이벤트가 발생하는 부분을 빠른 클릭을 하면 화면이나, 동작이 중복으로 발생하는 경우를 볼수 있습니다.

이전에는 버튼 마다 True/False Flag를 통해서 이벤트 중복 발생을 처리하였지만, 

버튼이 10개인 경우는 다처리 할수 있지만 1000/10000개 라고 극한상황을 설정하면 이와같은 방법은 그리 좋은 방법은 아닌것 같습니다.

그래서 스프링에서 AOP PointCut 을 사용했던 기억이있어 Android 에서도 사용할수 있는지 확인해보았습니다.



AOP 사용 준비


1. 클래스 패스를 추가합니다.

2. 플러그인을 적용합니다.

이와같이 준비를 하면 AOP PointCut 을 사용할 준비가 완료 되었습니다.


Add the plugin to your buildscript's dependencies section:

classpath 'com.uphyca.gradle:gradle-android-aspectj-plugin:0.9.14'

Apply the android-aspectj plugin:

apply plugin: 'com.uphyca.android-aspectj'


참고 : https://github.com/uPhyca/gradle-android-aspectj-plugin



AOP PointCut 사용


어노테이션을 사용했지만 여기서의 핵심은 @PointCut 어노테이션 입니다.

@PointCut으로 OnClickListener 를 지정하면 App 에서 동작하는 OnClickListener

이벤트를 캐치 할수 있습니다. 캐치하여 @Before @After 어노테이션을 통해 동작을 지정 할수 있습니다.

@Before 어노테이션을 통해서 처음 클릭시 View 클릭을 막아 주었고,

@After 어노테이션을 통해서 10초후 클릭을 할수 있도록 상태를 변경해 주었습니다.

테스트를 하기위해 10초는 극단적으로 테스트를 진행했습니다.

이와같이 AOP 개념을 이용하면 각각 버튼 마다 이벤트 중복 처리를 하지 않아도 간결하게 중복 방지를 할수 있습니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/**
 * Created by woong on 2017. 7. 20..
 */
 
@Aspect
public class BlockClick {
 
    private static final String TAG = "BlockClick";
 
    @Pointcut("execution(* android.view.View.OnClickListener.*(..))")
    public void onClickPoincut(){}
 
    @Before("onClickPoincut()")
    public void beforeOnClick(JoinPoint joinPoint){
 
        Log.i(TAG,">>>>>>>> beforeOnClick");
 
        Object[] args = joinPoint.getArgs();
        if(args.length > 0){
            View view = (View) args[0];
            view.setClickable(false);
        }
    }
 
    @After("onClickPoincut()")
    public void atferOnClick(JoinPoint joinPoint){
 
        Log.i(TAG,">>>>>>>> atferOnClick");
 
        Object[] args = joinPoint.getArgs();
        if(args.length > 0){
            final View view = (View) args[0];
            view.postDelayed(new Runnable() {
                @Override
                public void run() {
                    view.setClickable(true);
                }
            }, 10000);
        }
    }
}
 
cs


Comments