美文网首页
记一次优雅的回调方式

记一次优雅的回调方式

作者: changer0 | 来源:发表于2020-08-27 09:36 被阅读0次

最近在用 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<? 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

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

长按关注

相关文章

  • 记一次优雅的回调方式

    最近在用 Lifecycle 时学到了一种优雅的回调写法,特此记录一下。 普通回调 我们在写业务逻辑时难免会遇到需...

  • OpenCV 教程 02 : 创建滑块

    示例代码 回调函数方式 非回调函数方式 运行结果

  • ES7之Async/await的使用详解

    在 js 异步请求数据时,通常,我们多采用回调函数的方式解决,但是,如果有多个回调函数嵌套时,代码显得很不优雅,维...

  • iOS回调,异步回调实现,以及创建可取消的任务

    iOS下回调机制 在iOS下实现回调的方式 iOS下的代理模式实现方式利用protocol ,需要进行向外回调的实...

  • iOS 监听耳机插入和拔出[检索]

    使用通知的方式,添加收到通知的回调方法 响应通知回调。

  • iOS Cordova 多次回调callback

    cordova默认只能回调一次,回调一次后会被销毁,再回调js就收不到回调 方法:将 CDVPluginResul...

  • node 异步编程

    回调函数方式缺点:回调地狱、异步并发控制困难 Promise Async / Await

  • Promise

    Promise,js异步编程的流行解决方案,相比于古老的回调函数等方式,它更科学,更优雅。它来自民间,后被官方招安...

  • 异步的实现

    异步的三种实现方式: 回调函数事件Promise 回调函数 回调函数不一定是异步 但是异步一定是回调函数。 事件 ...

  • 回调方式总结

    今天对ios开发中常用的几种回调方式:block、delegate与NSNotification进行一下总结,并对...

网友评论

      本文标题:记一次优雅的回调方式

      本文链接:https://www.haomeiwen.com/subject/xezqsktx.html