美文网首页Harmony编程
鸿蒙系统事件总线框架—好雨

鸿蒙系统事件总线框架—好雨

作者: 裴云飞 | 来源:发表于2021-06-20 15:21 被阅读0次

    一、前言

    好雨是一款鸿蒙系统上的,基于ActiveData的事件总线框架。好雨一词来源于“好雨知时节,当春乃发生”,好雨知道下雨的节气,正是在春天植物萌发生长的时候。好雨是一款基于ActiveData的事件总线框架。ActiveData知道发送数据给观察者的时候正是宿主活跃的时候,宿主销毁的时候正是移除观察者的时候。

    二、好雨的特性

    • 消息随时订阅,当页面销毁的时候,自动移除订阅。
    • 解决事件总线引发的内存泄漏问题。
    • 解决因生命周期引发的崩溃问题。
    • 支持发送延迟消息和粘性消息。
    • 目前暂不支持跨进程发送消息,如果你有这方面的需求,可以向我提需求。

    三、源码

    源码
    要想读懂源码,需要先熟悉LifecycleActivaData,关于LifecycleActivaData,可以阅读鸿蒙系统之Lifecycle感知宿主的生命周期以及“好雨知时节,当春乃发生”的ActiveData
    关于好雨的实现原理,我在鸿蒙系统事件总线框架—好雨的实现原理
    这篇文章介绍了,在这片文章中,我不仅会介绍好雨的实现原理,还带领大家手写好雨框架,有兴趣的读者可以看下。

    四、添加依赖

    4、1 在项目根目录下的build.gradle文件中添加mavenCentral()仓库,打开项目根目录下的build.gradle文件,在build.gradle文件的repositories闭包下面添加mavenCentral()

    buildscript {
        repositories {
            mavenCentral()
            maven {
                url 'https://repo.huaweicloud.com/repository/maven/'
            }
            maven {
                url 'https://developer.huawei.com/repo/'
            }
            jcenter()
        }
        dependencies {
            classpath 'com.huawei.ohos:hap:2.4.4.2'
            classpath 'com.huawei.ohos:decctest:1.2.4.0'
        }
    }
    
    allprojects {
        repositories {
            mavenCentral()
            maven {
                url 'https://repo.huaweicloud.com/repository/maven/'
            }
            maven {
                url 'https://developer.huawei.com/repo/'
            }
            jcenter()
        }
    }
    

    4、2 打开entry目录下的build.gradle文件中,在build.gradle文件中的dependencies闭包下添加下面的依赖。

    implementation 'io.gitee.zhongte:haoyu:1.0.1'
    

    五、用法

    5、1先订阅消息,也就是注册观察者
    • 以感知生命周期的方式订阅消息,调用好雨对象的get方法来获取全局唯一的单例对象,调用with方法来获取被观察者对象,调用observe方法来注册观察者。
      需要注意的是,如果调用observe方法来注册观察者,那么只有当宿主处于活跃状态,观察者才能接收到消息。
    // with方法的参数是一个字符串,用来区分不同的消息
    HaoYu.get().with("key_observe", String.class)
            .observe(this, new DataObserver<String>() {
                @Override
                public void onChanged(String s) {
                    // 当宿主处于活跃状态,观察者才能接收到消息
                    Toast.show(MainAbilitySlice.this, s);
                }
            });
    
    • 订阅不受生命周期管理的消息,调用好雨对象的get方法来获取全局唯一的单例对象,调用with方法来获取被观察者对象,调用observeAlways方法来注册观察者。需要注意的是,如果调用observeAlways方法来注册观察者,那么在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也能接收到消息。
    HaoYu.get().with("key_observe", String.class)
            .observeAlways(this, new DataObserver<String>() {
                @Override
                public void onChanged(String s) {
                    // 接收不受生命周期管理的消息,即便宿主不活跃,观察者也能接收到消息
                    Toast.show(MainAbilitySlice.this, s);
                }
            });
    
    5、2订阅完消息后,就可以发送消息了
    • 发送任意类型的消息。调用好雨对象的get方法来获取全局唯一的单例对象,调用with方法来获取被观察者对象,调用post方法来发送消息。
    HaoYu.get().with("key_observe").post("消息");
    
    • 发送延迟消息,调用get方法来获取全局唯一的单例对象,调用with方法来获取被观察者对象,调用postDelay方法来发送消息。需要注意的是,当延迟时间到了后,只有宿主处在开始状态或者活跃状态时,才发送消息。
    HaoYu.get().with("key_test_observe_delay").postDelay(MainAbilitySlice.this, "延迟消息", 1000);
    
    5、3粘性消息

    上面的用法是先订阅消息,也就是注册观察者,订阅完消息后,才发送消息,这种消息是普通消息。粘性消息指的是先发送消息,后注册的观察者也能接收到之前发送的信息。
    发送粘性消息代码跟发生普通消息的代码是一样的

    HaoYu.get().with("key_test_sticky").post("粘性消息");
    

    接收粘性消息的代码跟接收普通消息的代码有点不一样,接收普通消息调用的是observe方法,接收粘性消息调用的是observeSticky方法,

    HaoYu.get().with(""key_test_sticky"", String.class)
            // 调用observeSticky方法接收粘性消息
            .observeSticky(this, new DataObserver<String>() {
            @Override
            public void onChanged(String s) {
                // 接收粘性消息
    
            }
    });
    

    看下面的例子,在当前页面发送消息,然后在下一个页面接收消息,这就是粘性消息。

    // 发送粘性消息,调用好雨对象的`get`方法来获取全局唯一的单例对象,调用`with`方法来获取被观察者对象,调用`observe`方法来注册观察者
    findComponentById(ResourceTable.Id_sticky).setClickedListener(new Component.ClickedListener() {
        @Override
        public void onClick(Component component) {
            // 发送粘性消息,在下一个页面接收粘性事件
            HaoYu.get().with("key_test_sticky").post("粘性消息");
            // 启动下一个页面
            present(new SecondAbilitySlice(), new Intent());
       }
    });
    

    在下一个页面注册观察者,接收粘性消息。

    public class SecondAbilitySlice extends AbilitySlice {
    
        private Text mText1;
    
        @Override
        public void onStart(Intent intent) {
            super.onStart(intent);
            super.setUIContent(ResourceTable.Layout_ability_second);
            mText1 = (Text) findComponentById(ResourceTable.Id_text);
            // 接收前一个页面发送过来的粘性消息
            HaoYu.get().with("key_test_sticky", String.class)
                    .observeSticky(this, new DataObserver<String>() {
                        @Override
                        public void onChanged(String s) {
                            mText1.setText(s);
                        }
                    });
        }
    
        @Override
        public void onActive() {
            super.onActive();
        }
    
        @Override
        public void onForeground(Intent intent) {
            super.onForeground(intent);
        }
    }
    

    六、详细用法

    获取全局唯一的单例对象。

    HaoYu.get()
    

    获取被观察者对象。

    /**
     * 获取被观察者对象
     *
     * @param eventName 事件的名称
     * @return 被观察者对象
     */
    public <T> Observable<T> with(String eventName)
    /**
     * 获取被观察者对象
     *
     * @param eventName 事件的名称
     * @param type 指定泛型的类型
     * @param <T> 指定泛型的类型
     * @return 被观察者对象
     */
    public <T> Observable<T> with(String eventName, Class<T> type)
    

    发送消息。

    /**
     * 发送消息
     *
     * @param value 消息
     */
    public void post(T value);
    

    延迟发送消息,当延迟时间到了后,只有宿主处在开始状态或者活跃状态时,才发送消息。

    /**
     * 延迟发送消息,当延迟时间到了后,只有宿主处在开始状态或者活跃状态时,才发送消息。
     *
     * @param lifecycle 宿主的生命周期
     * @param value 消息
     * @param delay 延迟时间
     */
    public void postDelay(ILifecycle lifecycle, T value, long delay)
    

    注册观察者,监听普通消息,只有当宿主活跃时,观察者才会接收到数据。

    /**
     * 注册观察者,监听普通消息,只有当宿主活跃时,观察者才会接收到数据。
     *
     * @param iLifecycle 宿主的生命周期
     * @param observer 观察者
     */
    void observe(ILifecycle iLifecycle, DataObserver<T> observer)
    

    注册观察者,监听普通消息,在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也会接收到数据。

    /**
     * 注册观察者,监听普通消息,在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也会接收到数据。
     *
     * @param iLifecycle 宿主的生命周期
     * @param observer 观察者
     */
    public void observeAlways(ILifecycle iLifecycle, DataObserver<T> observer)
    

    注册观察者,监听粘性消息,只有当宿主活跃时,观察者才会接收到数据。

    /**
     * 注册观察者,监听粘性消息,只有当宿主活跃时,观察者才会接收到数据。
     * 粘性消息指的是消息先发送,后注册的观察者也能接收到之前发送的信息。
     *
     * @param iLifecycle 宿主的生命周期
     * @param observer 观察者
     */
    public void observeSticky(ILifecycle iLifecycle, DataObserver<T> observer)
    

    注册观察者,监听粘性消息,在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也会接收到数据。

    /**
     * 注册观察者,监听粘性消息,在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也会接收到数据。
     *
     * @param iLifecycle 宿主的生命周期
     * @param observer 观察者
     */
    public void observeStickyAlways(ILifecycle iLifecycle, DataObserver<T> observer)
    

    最后,关于好雨的实现原理,我在鸿蒙系统事件总线框架—好雨的实现原理
    这篇文章介绍了,在这片文章中,我不仅会介绍好雨的实现原理,还带领大家手写好雨框架,有兴趣的读者可以看下。

    相关文章

      网友评论

        本文标题:鸿蒙系统事件总线框架—好雨

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