记一次优雅的回调方式

最近在用 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 注解相关的知识:

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 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

以上就是本节内容,欢迎大家关注

长按关注

你可能感兴趣的:(记一次优雅的回调方式)