記一次優雅的回調方式

最近在用 Lifecycle 時學到了一種優雅的回調寫法,特此記錄一下。

普通回調

我們在寫業務邏輯時難免會遇到需要設置回調的場景,也就是觀察者模式,例如下面這個觀察者:

public interface Observer {
    void call();
}

使用時直接添加即可。

public static void main(String[] args) {
    ObserverManager.addObserver(new Observer() {
        @Override
        public void call() {
            System.out.println("被調用~");
        }
    });
}

這種回調寫法比較簡單,而且開發中也最爲常用。

但是當我們觀察者接口的方法過多而且每次使用的回調方法只有其中的某幾個時,就會重寫很多無用方法!

新手同學可能會說可以用一個類來代替接口,有選擇的實現對應的回調方法。額,這肯定不行的,因爲類是沒有多繼承的,所以在使用時會有很多的限制。

註解回調

最近看了下 Lifecycle,發現他們在回調時使用的是註解的形式:

class LifecycleActivityObserver(val tvContent: TextView): LifecycleObserver {
    val loggerStr = StringBuilder()
    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onActivityCreate() {}

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onActivityResume() {}

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    fun onActivityPause() {}
}

這種寫法很巧妙的解決了上面提到的問題,接下來咱們看下是如何實現的。不過開始前需要簡單瞭解下 Java 註解相關的知識:

導圖摘自:https://www.cnblogs.com/peida/archive/2013/04/26/3038503.html

簡單瞭解後,寫一個自定義的註解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ObserverEvent {

    public enum Event {
        SUCCESS, FAILURE
    }
    
    Event value();
}

然後寫一個空接口,用來實現回調方法:

public interface Observer {
}

再寫一個 ObserverManager 用來模擬添加觀察者,實現數據的回調:

public class ObserverManager {

    public static void addObserver(final Observer observer) {
        Class<? extends Observer> clazz = observer.getClass();
        Method[] methods = clazz.getMethods();
        Method successMethod = null, failureMethod = null;
        //遍歷所有方法,找到被註解的方法
        for (Method method : methods) {
            ObserverEvent annotation = method.getAnnotation(ObserverEvent.class);
            if (annotation == null) {
                continue;
            }
            if (annotation.value() == ObserverEvent.Event.SUCCESS) {
                successMethod = method;
            } else if (annotation.value() == ObserverEvent.Event.FAILURE) {
                failureMethod = method;
            }
        }
        //測試 直接執行成功回調
        if (successMethod != null) {
            try {
                successMethod.invoke(observer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        //測試 延遲執行失敗回調
        if (failureMethod != null) {
            try {
                Thread.sleep(2000);
                failureMethod.invoke(observer);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

測試調用:

public static void main(String[] args) {
    ObserverManager.addObserver(new Observer() {
    
        @ObserverEvent(ObserverEvent.Event.SUCCESS)
        public void callSuccess() {
            System.out.println("成功回調");
        }
        
        @ObserverEvent(ObserverEvent.Event.FAILURE)
        public void callFailure() {
            System.out.println("失敗回調");
        }
    });
}

真正使用時我們會將 successMethod 和 failureMethod 保存到 List 中,在需要回調的場景中觸發回調。

Demo 地址

https://github.com/changer0/AnnotationCallback

以上就是本節內容,歡迎大家關注👇👇👇

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章