事件总线框架—好雨 精华

裴云飞1
发布于 2021-8-29 12:41
浏览
2收藏

一、前言

好雨是一款鸿蒙系统上的,基于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方法的第一个参数表示事件名称,用来区分不同的事件,表示观察者需要监听哪个事件。第二个参数表示观察者接收到的消息类型,如果观察者接收到的是一个字符串,那with方法的第二个参数就是String.class
// 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方法来注册观察者,那么在任何生命周期状态下都将消息发送给观察者,即便宿主不活跃,观察者也能接收到消息。 with方法的第一个参数表示事件名称,用来区分不同的事件,表示观察者需要监听哪个事件。第二个参数表示观察者接收到的消息类型,如果观察者接收到的是一个字符串,那with方法的第二个参数就是String.class
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方法来发送消息。with方法的参数表示事件名称,用来区分不同的事件。
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)

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

博客地址

分类
4
收藏 2
回复
举报
1条回复
按时间正序
/
按时间倒序
mb609898e2cfb86
mb609898e2cfb86

对比传统的框架,确实有很大的提升。

回复
2021-8-30 10:54:45
回复
    相关推荐