Android Studio:如何使用 RxBus 类进行事件发布和订阅
1. 依赖库
首先,确保你的 build.gradle
文件中包含了必要的 RxJava 和 RxAndroid 依赖。
2.创建 RxBus
类
public class RxBus {
private final SerializedSubject<Object, Object> subject;
public RxBus() {
subject = new SerializedSubject<>(PublishSubject.create());
}
public void post(Object object) {
subject.onNext(object);
}
@NonNull
public <T> Observable<T> toObservable(final Class<T> type) {
return subject.ofType(type);
}
public boolean hasObservers() {
return subject.hasObservers();
}
public <T> Subscription toSubscription(Class<T> type, Action1<T> action1) {
return this
.toObservable(type)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(action1);
}
public <T> Subscription toSubscription(Class<T> type, Action1<T> action1, Scheduler scheduler) {
return this
.toObservable(type)
.subscribeOn(scheduler)
.subscribe(action1);
}
}
subject
是一个 SerializedSubject
类型的实例,是 RxJava 中的一种特殊类型的 Observable
,它既是一个 Observer
,又是一个 Observable
。这意味着它可以同时接收和发射事件。
Observable
是一个数据流的提供者,订阅者可以从它接收事件。Observer
是一个事件的接收者,可以接收并处理从Observable
发出的事件。
简单来说,Subject
既能接收事件,也能发射事件,因此它既是观察者也是被观察者。
public <T> Subscription toSubscription(Class<T> type, Action1<T> action1) {
return this
.toObservable(type)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(action1);
}
public <T>
: 这是一个泛型方法,T
是一个占位符类型,表示方法可以接受任何类型的事件。这使得toSubscription
方法可以被用来订阅不同类型的事件,类型由调用时的type
参数指定。Class<T> type
: 这个参数是传递给方法的事件类型(例如String.class
或自定义的User.class
)。它用于指定你要订阅的事件的类型。Action1<T> action1
: 这个参数是一个回调函数,它的作用是在接收到相应类型的事件时执行。Action1<T>
是 RxJava 的一个接口,它接受一个类型为T
的对象并执行某些操作,但没有返回值。
subscribe(action1)
用来订阅 Observable
并传入一个回调 action1
,当事件(类型为 T
)被发射时,会调用 action1.call()
方法来处理事件。
- 当你调用
toSubscription()
方法时,它会返回一个Subscription
对象,表示你已经订阅了某个类型的事件(例如String
类型或User
类型的事件)。 toObservable(type)
会返回一个Observable
,它会发射类型为T
的事件。observeOn(AndroidSchedulers.mainThread())
将会确保事件的消费在主线程中执行。subscribe(action1)
会在事件被发射时调用action1.call()
来处理事件数据。
3. 创建事件类
假设我们有一个 User
类,它将作为我们发布和订阅的事件对象。
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
4. 主活动 (MainActivity)
在 MainActivity
中,我们将发布一个 User
类型的事件,并在同一个活动中订阅它。
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action1;
public class MainActivity extends AppCompatActivity {
private RxBus rxBus;
private Button publishButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rxBus = new RxBus(); // 创建 RxBus 实例
publishButton = findViewById(R.id.publishButton);
// 订阅 User 类型的事件
rxBus.toSubscription(User.class, new Action1<User>() {
@Override
public void call(User user) {
// 处理接收到的 User 对象
Log.d("RxBus", "Received User: " + user.getName() + ", " + user.getAge());
}
});
// 发布事件
publishButton.setOnClickListener(view -> {
User user = new User("John Doe", 30);
rxBus.post(user); // 发布 User 类型的事件
});
}
}
5. 布局文件 (activity_main.xml)
在 activity_main.xml
文件中,我们将放置一个按钮来触发事件的发布。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<Button
android:id="@+id/publishButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Publish Event" />
</LinearLayout>
6. 运行结果
- 当用户点击按钮时,
publishButton
的点击事件会触发,我们会创建一个User
对象,并通过RxBus
发布该事件。 RxBus
会将事件传递给所有订阅了User
类型的观察者。在这个例子中,观察者会在主线程中收到事件,并输出用户的name
和age
。