一、前言
好雨是一款鸿蒙系统上的,基于ActiveData的事件总线框架。好雨一词来源于“好雨知时节,当春乃发生”,好雨知道下雨的节气,正是在春天植物萌发生长的时候。好雨是一款基于ActiveData
的事件总线框架。ActiveData
知道发送数据给观察者的时候正是宿主活跃的时候,宿主销毁的时候正是移除观察者的时候。
二、好雨的特性
- 消息随时订阅,当页面销毁的时候,自动移除订阅。
- 解决事件总线引发的内存泄漏问题。
- 解决因生命周期引发的崩溃问题。
- 支持发送延迟消息和粘性消息。
- 目前暂不支持跨进程发送消息,如果你有这方面的需求,可以向我提需求。
三、源码
源码
要想读懂源码,需要先熟悉Lifecycle
和ActivaData
,关于Lifecycle
和ActivaData
,可以阅读鸿蒙系统之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)
最后,关于好雨的实现原理,我在鸿蒙系统事件总线框架—好雨的实现原理
这篇文章介绍了,在这片文章中,我不仅会介绍好雨的实现原理,还带领大家手写好雨框架,有兴趣的读者可以看下。
网友评论