国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android深思如何防止快速點(diǎn)擊

這篇具有很好參考價值的文章主要介紹了Android深思如何防止快速點(diǎn)擊。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

前言

其實(shí)快速點(diǎn)擊是個很好解決的問題,但是如何優(yōu)雅的去解決確是一個難題,本文主要是記錄一些本人通過解決快速點(diǎn)擊的過程中腦海里浮現(xiàn)的一些對這個問題的深思。

作者:流浪漢kylin 鏈接:https://juejin.cn/post/7197337416096055351

1. AOP

可以通過AOP來解決這個問題,而且AOP解決的方法也很優(yōu)雅,在開源上也應(yīng)該是能找到對應(yīng)的成熟框架。

AOP來解決這類問題其實(shí)是近些年一個比較好的思路,包括比如像數(shù)據(jù)打點(diǎn),通過AOP去處理,也能得到一個比較優(yōu)雅的效果。牛逼的人甚至可以不用別人寫的框架,自己去封裝就行,我因為對這個技術(shù)棧不熟,這里就不獻(xiàn)丑了。
總之,如果你想快速又簡單的處理這種問題,AOP是一個很好的方案

2. kotlin

使用kotlin的朋友有福了,kotlin中有個概念是擴(kuò)展函數(shù),使用擴(kuò)展函數(shù)去封裝放快速點(diǎn)擊的操作邏輯,也能很快的實(shí)現(xiàn)這個效果。它的好處就是突出兩個字“方便”

那是不是我用java,不用kotlin就實(shí)現(xiàn)不了kotlin這個擴(kuò)展函數(shù)的效果?當(dāng)然不是了。這讓我想到一件事,我也有去看這類問題的文章,看看有沒有哪個大神有比較好的思路,然后我注意到有人就說用擴(kuò)展函數(shù)就行,不用這么麻煩。

OK,那擴(kuò)展函數(shù)是什么?它的原理是什么?不就是靜態(tài)類去套一層嗎?那用java當(dāng)然能實(shí)現(xiàn),為什么別人用java去封裝這套邏輯就是麻煩呢?代碼不都是一樣,只不過kotlin幫你做了而已。所以我覺得kotlin的擴(kuò)展函數(shù)效果是方便,但從整體的解決思路上看,缺少點(diǎn)優(yōu)雅。

3. 流

簡單來說也有很多人用了Rxjava或者kotlin的flow去實(shí)現(xiàn),像這種實(shí)現(xiàn)也就是能方便而已,在底層上并沒有什么實(shí)質(zhì)性的突破,所以就不多說了,說白了就是和上面一樣。

4. 通過攔截

因為上面已經(jīng)說了kt的情況,所以接下來的相關(guān)代碼都會用java來實(shí)現(xiàn)。
通過攔截來達(dá)到防止快速點(diǎn)擊的效果,而攔截我想到有2種方式,第一種是攔截事件,就是基于事件分發(fā)機(jī)制去實(shí)現(xiàn),第二種是攔截方法。
相對而言,其實(shí)我覺得攔截方法會更加安全,舉個場景,假如你有個頁面,然后頁面正在到計算,到計算完之后會顯示一個按鈕,點(diǎn)擊后彈出一個對話框。然后過了許久,改需求了,改成到計算完之后自動彈出對話框。但是你之前的點(diǎn)擊按鈕彈出對話框的操作還需要保留。那就會有可能因為某些操作導(dǎo)致到計算完的一瞬間先顯示按鈕,這時你以迅雷不及掩耳的速度點(diǎn)它,那就彈出兩次對話框。

(1)攔截事件

其實(shí)就是給事件加個判斷,判斷兩次點(diǎn)擊的時間如果在某個范圍就不觸發(fā),這可能是大部分人會用的方式。

正常情況下我們是無法去入侵事件分發(fā)機(jī)制的,只能使用它提供的方法去操作,比如我們沒辦法在外部影響dispatchTouchEvent這些方法。當(dāng)然不正常的情況下也許可以,你可以嘗試往hook的方向去思考能不能實(shí)現(xiàn),我這邊就不思考這種情況了。

public class FastClickHelper {
    private static long beforeTime = 0;    private static Map<View, View.OnClickListener> map = new HashMap<>();
    public static void setOnClickListener(View view, View.OnClickListener onClickListener) {        map.put(view, onClickListener);        view.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                long clickTime = SystemClock.elapsedRealtime();                if (beforeTime != 0 && clickTime - beforeTime < 1000) {                    return;                }                beforeTime = clickTime;
                View.OnClickListener relListener = map.get(v);                if (relListener != null) {                    relListener.onClick(v);                }            }        });    }
}
 

簡單來寫就是這樣,其實(shí)這個就和上面說的kt的擴(kuò)展函數(shù)差不多。調(diào)用的時候就

FastClickHelper.setOnClickListener(view, this);

但是能看出這個只是針對單個view去配置,如果我們想其實(shí)頁面所有view都要放快速點(diǎn)擊,只不過某個view需要快速點(diǎn)擊,比如搶東西類型的,那肯定不能防。所以給每個view單獨(dú)去配置就很麻煩,沒關(guān)系,我們可以優(yōu)化一下

public class FastClickHelper {
    private Map<View, Integer> map;    private HandlerThread mThread;
    public void init(ViewGroup viewGroup) {        map = new ConcurrentHashMap<>();        initThread();        loopAddView(viewGroup);
        for (View v : map.keySet()) {            v.setOnTouchListener(new View.OnTouchListener() {                @Override                public boolean onTouch(View v, MotionEvent event) {                    if (event.getAction() == MotionEvent.ACTION_DOWN) {                        int state = map.get(v);                        if (state == 1) {                            return true;                        } else {                            map.put(v, 1);                            block(v);                        }                    }                    return false;                }            });        }    }
    private void initThread() {        mThread = new HandlerThread("LAZY_CLOCK");        mThread.start();    }
    private void block(View v) {        // 切條線程處理        Handler handler = new Handler(mThread.getLooper());        handler.postDelayed(new Runnable() {            @Override            public void run() {                if (map != null) {                    map.put(v, 0);                }            }        }, 1000);    }
    private void exclude(View... views) {        for (View view : views) {            map.remove(view);        }    }
    private void loopAddView(ViewGroup viewGroup) {        for (int i = 0; i < viewGroup.getChildCount(); i++) {            if (viewGroup.getChildAt(i) instanceof ViewGroup) {                ViewGroup vg = (ViewGroup) viewGroup.getChildAt(i);                map.put(vg, 0);                loopAddView(vg);            } else {                map.put(viewGroup.getChildAt(i), 0);            }        }    }
    public void onDestroy() {        try {            map.clear();            map = null;            mThread.interrupt();        } catch (Exception e) {            e.printStackTrace();        }    }
}

我把viewgroup當(dāng)成入?yún)ⅲ缓蠼o它的所有子view都設(shè)置,因為onclicklistener比較常用,所以改成了設(shè)置setOnTouchListener,當(dāng)然外部如果給view設(shè)置了setOnTouchListener去覆蓋我這的set,那就只能自己做特殊處理了。

在外部直接調(diào)用

FastClickHelper fastClickHelper = new FastClickHelper();fastClickHelper.init((ViewGroup) getWindow().getDecorView());

如果要想讓某個view不要限制快速點(diǎn)擊的話,就調(diào)用exclude方法。這里要注意使用完之后釋放資源,要調(diào)用onDestroy方法釋放資源。

關(guān)于這個部分的思考,其實(shí)上面的大家都會,也基本是這樣去限制,但是就是即便我用第二種代碼,也要每個頁面都調(diào)用一次,而且看起來,多少差點(diǎn)優(yōu)雅。

首先我想的辦法是在事件分發(fā)下發(fā)的過程去做處理,就是在viewgroup的dispatchTouchEvent或者onInterceptTouchEvent這類方法里面,但是我簡單看了源碼是沒有提供方法出來的,也沒有比較好去hook的地方,所以只能暫時放棄思考在這個下發(fā)流程去做手腳。

補(bǔ)充一下,如果你是自定義view,那肯定不會煩惱這個問題,但是你總不能所有的view都做成自定義的吧。

其次我想怎么能通過不寫邏輯代碼能實(shí)現(xiàn)這個效果,但總覺得這個方向不就是AOP嗎,或者不是通過開發(fā)層面,在開發(fā)結(jié)束后想辦法去注入字節(jié)碼等操作,我覺得要往這個方向思考的話,最終的實(shí)現(xiàn)肯定不是代碼層面去實(shí)現(xiàn)的。

(2)攔截方法

上面也說了,相對于攔截事件,假設(shè)如果都能實(shí)現(xiàn)的情況下,我更傾向于去攔截方法。

因為從這層面上來說,如果實(shí)現(xiàn)攔截方法,或者說能實(shí)現(xiàn)中斷方法,那就不只是能做到防快速點(diǎn)擊,而是能給方法去定制相對應(yīng)的規(guī)則,比如某個方法在1秒的間隔內(nèi)只能調(diào)用一次,這個就是防快速點(diǎn)擊的效果嘛,比如某個方法我限制只能調(diào)一次,如果能實(shí)現(xiàn),我就不用再額外寫判斷這個方法調(diào)用一次過后我設(shè)置一個布爾類型,然后下次調(diào)用再判斷這個布爾類型來決定是否調(diào)用,

那現(xiàn)在是沒辦法實(shí)現(xiàn)攔截方法嗎?當(dāng)然有辦法,只不過會十分的不優(yōu)雅,比如一個方法是這樣的。

public void fun(){    // todo 第1步    // todo 第2步    // todo ......    // todo 第n步}

那我可以封裝一個類,里面去封裝一些策略,然后根據(jù)策略再去決定方法要不要執(zhí)行這些步驟,那可能就會寫成

public void fun(){    new FunctionStrategy(FunctionStrategy.ONLY_ONE, new CallBack{        @Override        public void onAction() {            // todo 第1步            // todo 第2步            // todo ......            // todo 第n步        }    })}

這樣就實(shí)現(xiàn)了,比如只調(diào)用一次,具體的只調(diào)用一次的邏輯就寫在FunctionStrategy里面,然后第2次,第n次就不會回調(diào)。當(dāng)然我這是隨便亂下來表達(dá)這個思路,現(xiàn)實(shí)肯定不能這樣寫。首先這樣寫就很不優(yōu)雅,其次也會存在很多問題,擴(kuò)展性也很差。

那在代碼層面還有其它辦法攔截或者中斷方法嗎,在代碼層還真有辦法中斷方法,沒錯,那就是拋異常,但是話說回來,你也不可能在每個地方都try-catch吧,不切實(shí)際。

目前對攔截方法或者中斷方法,我是沒想到什么好的思路了,但是我覺得如果能實(shí)現(xiàn),對防止快速點(diǎn)擊來說,肯定會是一個很好的方案。文章來源地址http://www.zghlxwxcb.cn/news/detail-692257.html

到了這里,關(guān)于Android深思如何防止快速點(diǎn)擊的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 如何在 Android 應(yīng)用中使用 RecyclerView 實(shí)現(xiàn)一個列表顯示,并實(shí)現(xiàn)點(diǎn)擊事件?

    首先,需要在項目的 build.gradle 文件中添加 RecyclerView 的依賴: 接下來,在布局文件中添加 RecyclerView: 接著,需要創(chuàng)建一個 Adapter 類,用于將數(shù)據(jù)綁定到 RecyclerView 上,如下所示: 在 onBindViewHolder() 方法中,我們可以將數(shù)據(jù)綁定到 ViewHolder 中的視圖上。 需要注意的是,在 V

    2024年02月05日
    瀏覽(25)
  • Android 如何在Android studio中快速創(chuàng)建raw和assets文件夾

    Android 如何在Android studio中快速創(chuàng)建raw和assets文件夾

    1. 創(chuàng)建raw文件夾 切成project瀏覽模式——找到res文件粘貼要放入raw文件夾下的文件。 當(dāng)然此時raw文件還沒有,直接在右側(cè)輸入框中出現(xiàn)的路徑~res后面加上raw即可。 2. 創(chuàng)建assets文件夾 同理在main文件夾下粘貼要放入assets文件夾的文件,添加對應(yīng)的assets路徑即可生成。 路徑很難

    2024年02月06日
    瀏覽(19)
  • 防止Android截屏

    一、背景介紹 對于涉及用戶個人隱私的應(yīng)用,比如銀行、支付、社交等應(yīng)用,其界面中可能會涉及到用戶的個人信息,比如手機(jī)號、身份證號碼、交易記錄等。如果這些信息被人截屏,就可能會造成用戶個人隱私的泄露。 另外一方面,一些企業(yè)和開發(fā)者可能會開發(fā)一些自己

    2024年02月08日
    瀏覽(19)
  • android如何通過adb快速開啟、關(guān)閉輔助副屏

    android如何通過adb快速開啟、關(guān)閉輔助副屏

    adb 指令 效果

    2024年02月01日
    瀏覽(23)
  • Android問題筆記四十三:JNI 開發(fā)如何快速定位崩潰問題

    Android問題筆記四十三:JNI 開發(fā)如何快速定位崩潰問題

    Unity3D特效百例 案例項目實(shí)戰(zhàn)源碼 Android-Unity實(shí)戰(zhàn)問題匯總 游戲腳本-輔助自動化 Android控件全解手冊 再戰(zhàn)Android系列 Scratch編程案例 軟考全系列 Unity3D學(xué)習(xí)專欄 藍(lán)橋系列 ChatGPT和AIGC 專注于 Android/Unity 和各種游戲開發(fā)技巧,以及 各種資源分享 (網(wǎng)站、工具、素材、源碼、游戲等

    2024年02月05日
    瀏覽(23)
  • 如何在 Android 上恢復(fù)已刪除的視頻|快速找回丟失的記憶

    如何在 Android 上恢復(fù)已刪除的視頻|快速找回丟失的記憶

    想知道是否有任何成功的方法可以從 Android 手機(jī)中檢索已刪除的視頻?好吧,本指南將向您展示分步說明,讓您輕松從手機(jī)中找回丟失的視頻文件! 您是否不小心從 Android 智能手機(jī)中刪除了珍貴的生日視頻?難道是無處可尋嗎?你做什么工作?恐慌?嗯,你當(dāng)然不需要。通過

    2024年02月14日
    瀏覽(52)
  • 5G時代下,Android音視頻強(qiáng)勢崛起,我們該如何快速入門音視頻技術(shù)?

    5G時代下,Android音視頻強(qiáng)勢崛起,我們該如何快速入門音視頻技術(shù)?

    作為Android開發(fā)者的我們到底應(yīng)不應(yīng)該上音視頻這條船? 接下來一起分析下。 大趨勢 從未來的大趨勢來看,隨著5G時代的到來,音視頻慢慢變成人們?nèi)粘I钪械谋匦杵贰3嗽诰€教育、音視頻會議、即時通訊這些必須使用音視頻技術(shù)的產(chǎn)品外,其它的產(chǎn)品也需要加入音頻、

    2024年04月15日
    瀏覽(28)
  • 不會代碼(實(shí)操能力弱一點(diǎn))的我如何快速開發(fā)出一個Android/Web/IOS/小程序

    不會代碼(實(shí)操能力弱一點(diǎn))的我如何快速開發(fā)出一個Android/Web/IOS/小程序

    像做PPT一樣的可視化編程語言你想擁有嗎,可以自己嘗試一下。 像PPT一樣的編程語言 抽象出超過200+前端和后臺原子組件,每個組件都具備“不可拆分”特性,并表達(dá)獨(dú)立具有特征的屬性;同時每個組件都具備“屬性”“觸發(fā)條件”“功能(函數(shù))”。 邏輯編輯框架:(專利

    2024年02月09日
    瀏覽(31)
  • android實(shí)現(xiàn)點(diǎn)擊按鈕切換頁面

    android實(shí)現(xiàn)點(diǎn)擊按鈕切換頁面

    一、實(shí)現(xiàn)的功能 點(diǎn)擊頁面按鈕,切換到下一個頁面。 二、主要代碼 1)第一個頁面 我們需要實(shí)現(xiàn)點(diǎn)擊登錄按鈕進(jìn)行頁面切換 layout中設(shè)置一個Button,僅展示按鈕部分代碼 ?登錄頁面LoginActivity代碼, 三、啟動頁面 啟動頁面要設(shè)置為第一個頁面,在AndroidMainfest.xml

    2024年02月08日
    瀏覽(25)
  • App防止惡意截屏功能的方法:iOS、Android和鴻蒙系統(tǒng)的實(shí)現(xiàn)方案

    App防止惡意截屏功能的方法:iOS、Android和鴻蒙系統(tǒng)的實(shí)現(xiàn)方案

    防止應(yīng)用被截圖是一個比較常見的需求,主要是出于安全考慮。下面將分別為iOS(蘋果系統(tǒng))、Android(安卓系統(tǒng))及HarmonyOS(鴻蒙系統(tǒng))提供防止截屏的方法和示例代碼。 在企業(yè)內(nèi)部使用的應(yīng)用中,防止員工惡意截屏是一個重要的安全需求。本文將詳細(xì)介紹iOS、Android和鴻蒙

    2024年02月04日
    瀏覽(34)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包