【Android AOP--02】防止按鈕連續(xù)點(diǎn)擊

如果連續(xù)多次點(diǎn)擊按鈕會(huì)造成打開(kāi)多個(gè)重復(fù)頁(yè)面,或者多次請(qǐng)求,造成數(shù)據(jù)混亂。所以很多時(shí)候,我們需要避免這種情況發(fā)生。下面就通過(guò)AOP來(lái)實(shí)現(xiàn)這個(gè)功能。

1、定義一個(gè)防止多次點(diǎn)擊的工具類(lèi)


/**
 * 防止按鈕2連續(xù)多次點(diǎn)擊
 * Created by zhouxu on 2018/9/17.
 */

public class NoDoubleClickUtils {
    private final static int SPACE_TIME = 500;//2次點(diǎn)擊的間隔時(shí)間,單位ms
    private static long lastClickTime;

    public synchronized static boolean isDoubleClick() {
        long currentTime = System.currentTimeMillis();
        boolean isClick;
        if (currentTime - lastClickTime > SPACE_TIME) {
            isClick = false;
        } else {
            isClick = true;
        }
        lastClickTime = currentTime;
        return isClick;
    }
}

2、使用AspectJ創(chuàng)建切面類(lèi),處理Poincuts等

@Aspect
public class AspectTest {
    final String TAG = AspectTest.class.getSimpleName();

    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickLitener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Log.e(TAG, "OnClick");
        if (!NoDoubleClickUtils.isDoubleClick()) {
           proceedingJoinPoint.proceed();
       }
    }
}

@Aspect:表示這是一個(gè)切面類(lèi)

@Around:環(huán)繞通知,會(huì)攔截原方法內(nèi)容的執(zhí)行,也就是說(shuō)會(huì)攔截Activity中的onclick(),只執(zhí)行AspectTest的onClickLitener()

proceedingJoinPoint.proceed();:表示這個(gè)方法執(zhí)行完畢了,可以放開(kāi)攔截了,接下來(lái)就會(huì)執(zhí)行Activity中的onclick()

"execution(* android.view.View.OnClickListener.onClick(..))":表示切點(diǎn),也就是說(shuō)所有的點(diǎn)擊事件,都會(huì)執(zhí)行這個(gè)方法。

3、Activity中無(wú)需添加任何代碼

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "button1 onClick: ");
            }
        });

    }

連續(xù)點(diǎn)擊的運(yùn)行結(jié)果


可以看出在Activity的onclick處只執(zhí)行了一次,也就是說(shuō)通過(guò)AOP這種方式,在不侵入原有代碼的情況下,就實(shí)現(xiàn)了防止連續(xù)點(diǎn)擊的功能。

如果說(shuō)要求部分按鈕是可以連續(xù)點(diǎn)擊的

這種情況,就需要自定義Pointcuts了。

1、自定義注解接口

/**
 * 自定義Pointcuts
 * Created by zhouxu on 2018/9/17.
 */

@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface DoubleClick {
}

2、處理切面的類(lèi)AspectTest

@Aspect
public class AspectTest {
    final String TAG = AspectTest.class.getSimpleName();

    private boolean isDoubleClick = false;

    @Before("execution(@com.zx.aopdemo.DoubleClick  * *(..))")
    public void beforeEnableDoubleClcik(JoinPoint joinPoint) throws Throwable {
        Log.e(TAG, "beforeEnableDoubleClcik: ");
        isDoubleClick = true;
    }

    @Around("execution(* android.view.View.OnClickListener.onClick(..))")
    public void onClickLitener(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Log.e(TAG, "OnClick");
//        if (!NoDoubleClickUtils.isDoubleClick()) {
//            proceedingJoinPoint.proceed();
//        }

        if (isDoubleClick || !NoDoubleClickUtils.isDoubleClick()) {
            proceedingJoinPoint.proceed();
            isDoubleClick = false;
        }
    }

}

3、在Activity中允許點(diǎn)擊的onclick前加一個(gè)@DoubleClick的注解就好

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        testAOP();

        findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "button1 onClick: ");
            }
        });


        findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() {
            @DoubleClick
            @Override
            public void onClick(View v) {
                //允許連續(xù)點(diǎn)擊
                Log.e(TAG, "button2 onClick: ");
            }
        });

    }
}

連續(xù)點(diǎn)擊button2的運(yùn)行結(jié)果


可以發(fā)現(xiàn)button1是不能連續(xù)點(diǎn)擊的,而加了@DoubleClick注解的button2是可以連續(xù)點(diǎn)擊的

參考文章:AOP在Android中的應(yīng)用-過(guò)濾重復(fù)點(diǎn)擊

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容