一款簡單的消息防抖框架

WQthrottle 是一款消息防抖框架,在必定的時間延時中作到只觸發一次結果的回調。java

使用

使用的話,仍是看 github 的 README 吧。git

開發目的

開發這款框架的初衷是爲了解決如下的幾個痛點:github

  • 多餘的操做請求
  • 多頁面消息傳遞

痛點一(多餘的操做請求)

這個痛點在咱們的業務中常常出現,下面列出兩個比較常見的業務操做:服務器

點贊

在咱們設計點讚的時候,每點擊一次  操做都會請求服務器,以告知服務器當前是 點贊 操做仍是 取消贊 操做,若是用戶這時頻繁去點贊,就會致使過多的網絡請求,產生了沒必要要的浪費。對於設計層面來講,點贊功能無非就是兩種狀態,贊或是沒贊 ,咱們徹底能夠等待用戶中止操做後再去請求服務器。網絡

搜索

實時搜索展現搜索內容也是咱們平時業務中比較常見的功能,咱們給 EditText 註冊 TextWatcher 監聽,在 onTextChanged 中實時拿到用戶輸入的內容而後請求網絡,看似一段沒有任何問題的操做,就敗在不一樣用戶的輸入習慣,有的人打字很是慢,打入一些詞組,onTextChanged 收到消息立馬請求服務器顯示結果,而有的人打字很是快,並且每打一個詞組就回車到 EditText 上,這就會致使頻繁的網絡請求,更糟糕的狀況就是頻繁的頁面渲染,100次請求就會致使100次的頁面渲染。框架

痛點二(多頁面消息傳遞)

在剛接觸 Android 開發時,頁面的消息傳遞通常都是 Intent ,回傳經過 setResult 將結果帶回上一個頁面,很是蛋疼的操做,直到後來出現 EventBus ,在業內很是流行,一款很是解耦的框架,能夠作到在任何地方發送消息和接收消息,但對於我來講,缺點仍是蠻多的:ide

  • Subcribe 太隨意,致使後面項目亂,很差維護
  • Eventbus 的內部實現原理是反射,性能問題須要斟酌
  • 每次 post 一個消息過去都要想,我這個 bean 會不會影響到其餘的消息接收,算了,仍是建立一個 bean 類吧

原理剖析

實現原理很是簡單, 就一個核心東西------《Handler》 oop

初始化

初始化操做使用的單例,他會默認構造一個 handler 處理類:post

handler = HandlerFactory.create(HandlerType.MAIN_THREAD, callBacks);
複製代碼

HandlerType 是一個枚舉類,該枚舉主要爲了告知接收器是在主線程仍是子線程,具體可看 HandlerFactory 類。性能

註冊

註冊很是簡單,就是註冊一個 CallBack 接口,等 post 消息時,會一一回調註冊的 callback

private List<CallBack> callBacks = new ArrayList<>();
public void register(CallBack callBack) {
        callBacks.add(callBack);
}
複製代碼

發送消息

發送消息整個框架的核心部分:

WQThrottle.getInstance().delay(int tag, long timeMillis, Object params);
複製代碼

咱們來看下 delay 作的什麼東西:

public void delay(int tag, long timeMillis, Object params) {
        handler.removeMessages(tag);
        Message msg = handler.obtainMessage();
        msg.obj = params;
        msg.what = tag;
        handler.sendMessageDelayed(msg, timeMillis);
   }
複製代碼

仍是很是簡單,就是在 delay 時間內,移除以前觸發的消息,而後從新發送消息,直到用戶不觸發了,等 delay 時間到了,消息就會發送出去了。

消息接收

消息的接收須要先看看回調部分的代碼:

new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                sendMessages(msg, callBacks);
            }
};

private static void sendMessages(Message msg, List<WQThrottle.CallBack> callBacks) {
        for (int i = 0, len = callBacks.size(); i < len; i++) {
            callBacks.get(i).throttleResult(msg.what, msg.obj);
        }
}
複製代碼

發送的消息被 Handler 接收到了,會遍歷全部 CallBack 註冊接口,將信息 post 出去。

@Override
 public void throttleResult(int tag, Object obj) {
     switch(tag){//do something}
 }
複製代碼

CallBack 根據發送的 tag 進行比較,肯定是什麼操做,而後取出參數 obj。

結束

整個設計很是簡單,僅僅只經過 Handler 就實現了基於消息的框架。

話很少,就這樣吧

相關文章
相關標籤/搜索