RxBus2:基于RxJava2的RxBus

基于RxJava2的RxBus2. 主要用于发送事件/订阅事件.类似EventBus. 支持Kotlin
欢迎访问我的GitHub地址:https://github.com/wind0ws/rxbus2
源码和使用示例都在上面。欢迎star和fork以及PR.

目前版本:V1.1.1, JavaDoc 文档:请点这里查看

特点

  • 支持注解方式订阅事件。
  • 支持粘滞事件。
  • 支持3种Bus:
    • Publish Bus( RxBus,参见 PublishSubject )
    • Behavior Bus(参见 BehaviorSubject)
    • Replay Bus(参见ReplaySubject)

集成

在项目的gradle中配置

allprojects {
 repositories {
    jcenter()
    maven { url "https://jitpack.io" }
 }
}

在要集成RxBus2的模块的gradle中配置

 implementation group: 'io.reactivex.rxjava2', name: 'rxjava', version: '2.x.x'
    implementation('com.jakewharton.rxrelay2:rxrelay:2.0.0'){
        exclude group: 'io.reactivex.rxjava2',module: 'rxjava'
    }
implementation "com.github.wind0ws:rxbus2:1.1.1"

请将上面的2.x.x改成最新版本。截止到目前,最新的RxJava2版本是2.1.8
如果你的AndroidStudio是2.x版本,那么你需要把implementation关键词换成compile
如果对配置gradle有任何疑问,请参见项目的gradle文件

配置(可选)

RxBus2是个纯粹的Java库,这意味着并没有集成与Android有关的任何东西,就像RxJava.
所以,如果在Android中使用注解(RxSubscribe)在主线程(UI线程)上处理订阅的事件,那么你需要配置一下RxBus 的主线程 Scheduler.配置很简单,在Application的onCreate()方法里写一句话即可。

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        RxBus.setMainScheduler(AndroidSchedulers.mainThread());
    }
}

AndroidSchedulers是RxAndroid库里的内容。
如果AndroidStudio提示找不到AndroidSchedulers,请记得先在gradle中引入RxAndroid

使用

这里以常用的RxBus(ReplayBus、BehaviorBus同理)为例。

这里先解释下什么是订阅粘滞事件和订阅普通事件:

  • 订阅普通事件:只有建立订阅关系后发出的 事件 才能收到。
  • 订阅粘滞事件:在建立订阅关系前发出的 粘滞事件 也能收到。

如果还有不明白的,建议看看Android里的 粘滞广播普通广播.

注意事件本身不区分是普通的还是粘滞的,你只需要在发事件的时候告诉RxBus你发的事件是普通的还是粘滞的。

  1. 发事件:
    发普通事件:post(event)
    发粘滞事件:postSticky(event)
  2. 订阅事件:
    订阅普通事件: ofType(String.class)
    订阅粘滞事件:ofStickyType(String.class)

对于粘滞事件,还有一些高级用法,比如移除某个粘滞事件,清除某种类型的粘滞事件,清除所有粘滞事件等。这些可以去RxBus中查看源码和文档。

1. 手动订阅/解除订阅

手动订阅的记得要在合适的地方解除订阅哦!
比如在Android Activity里,在onDestroy里解除订阅关系,否则会发生内存泄露(也就是对象无法释放。)

 @Override
    protected void onDestroy() {
       // manual listen event should release by yourself.
        if (mCompositeDisposable != null) {
            mCompositeDisposable.clear();
        }
        super.onDestroy();
    }

首先在类里创建一个对象:

CompositeDisposable mCompositeDisposable = new CompositeDisposable();
  • 订阅普通事件
Disposable subscribe =
RxBus.getDefault()
                .ofType(String.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(String s) throws Exception {
                        String text = "{ [" + tag + "]:" + s+" }";
                        Log.d("RxBus”,text);
                    }
                });
  mCompositeDisposable.add(subscribe);//管理订阅对象,方便释放
  RxBus.getDefault().post("Normal Event");

日志输出 Normal Event

  • 订阅粘滞事件
RxBus.getInstance().postSticky("Sticky Event");
Disposable subscribe =
RxBus.getDefault()
                .ofStickyType(String.class)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(String s) throws Exception {
                        String text = "{ [" + tag + "]:" + s+" }";
                        Log.d("RxBus”,text);
                    }
                });
mCompositeDisposable.add(subscribe);//管理订阅对象,方便释放
RxBus.getDefault().post("Normal Event");

日志输出 Sticky EventNormal Event

2. 注解方式订阅

  • 编写订阅事件方法
    方法名随意,但是方法里有且仅有一个参数!方法可以为public,也可以用private修饰。
  • 订阅普通事件
    @RxSubscribe(observeOnThread = EventThread.MAIN) 
    public void listenRxIntegerEvent(int code) {
        String text = String.format("{ Receive event: %s\nCurrent thread: %s }", code, Thread.currentThread());
        Log.d("RxBus",text)
    }
  • 订阅粘滞事件
@RxSubscribe(observeOnThread = EventThread.IO,isSticky = true)
    private void listenRxStringEvent(String event) {
        final String text = String.format("{ Receive event: %s\nCurrent thread: %s }", event, Thread.currentThread());
        Log.d("RxBus",text);
    }
  • 注册和取消注册订阅事件.
    • 注册:
 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rx_bus);
        RxBus.getDefault().register(this);
    }
  • 取消注册:
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //auto release register with Annotation RxSubscribe.
        RxBus.getDefault().unregister(this);
    }

这里要说明一下,RxBus支持注解方式订阅和粘滞事件。BehaviorBus和ReplayBus都是不支持的(仅支持手动订阅和发普通事件。为什么不支持注解呢,因为这两种并不常(我)用(懒)。至于不支持粘滞事件,那是因为这两个天生不合适(这是真的). 比如对于ReplayBus, 他发的每个事件就是粘滞事件(因为每个订阅者不管什么时候订阅都能获取到订阅前的所有事件))。
想必理解三种Bus特点的同学估计已经知道原因了。不明白的请看看PublishSubject、BehaviorSubject、ReplaySubject的不同点: 参见这里

混淆与常见问题

  • 如果使用注解(@RxSubscribe),那么请注意在progurad-rules.pro中加入混淆规则,以防release版注解被混淆
# For using annotation
-keepattributes *Annotation*
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations

-keepclassmembers class ** {
    @com.threshold.rxbus2.annotation.RxSubscribe ;
}
-keep enum com.threshold.rxbus2.util.EventThread { *; }
  • 对于 Failed resolution of: Lcom/jakewharton/rxrelay2/PublishRelayDidn't find class "com.jakewharton.rxrelay2.PublishRelay"这样的错误,肯定是在模块的build.gradle的没有集成 com.jakewharton.rxrelay2:rxrelay
09-24 22:52:37.531 E/AndroidRuntime: FATAL EXCEPTION: main
                                    Process: com.threshold.learningdriving, PID: 1677
                                    java.lang.NoClassDefFoundError: Failed resolution of: Lcom/jakewharton/rxrelay2/PublishRelay;
                                        at com.threshold.rxbus2.RxBus.(RxBus.java:79)
                                        at com.threshold.rxbus2.RxBus.getDefault(RxBus.java:63)
                                        at com.threshold.rxbus2.RxBus.getInstance(RxBus.java:51)
                                        at com.threshold.learningdriving.ui.activity.LoginActivity.initRxBusEvent(LoginActivity.java:125)
                                        at com.threshold.learningdriving.ui.activity.LoginActivity.onResume(LoginActivity.java:148)
                                        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269)
                                        at android.app.Activity.performResume(Activity.java:6783)
                                        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406)
                                        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469)
                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732)
                                        at android.app.ActivityThread.-wrap12(ActivityThread.java)
                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
                                        at android.os.Handler.dispatchMessage(Handler.java:102)
                                        at android.os.Looper.loop(Looper.java:154)
                                        at android.app.ActivityThread.main(ActivityThread.java:6119)
                                        at java.lang.reflect.Method.invoke(Native Method)
                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
                                     Caused by: java.lang.ClassNotFoundException: Didn't find class "com.jakewharton.rxrelay2.PublishRelay" on path: DexPathList[[zip file "/data/app/com.threshold.learningdriving-1/base.apk"],nativeLibraryDirectories=[/data/app/com.threshold.learningdriving-1/lib/x86, /data/app/com.threshold.learningdriving-1/base.apk!/lib/x86, /system/lib, /vendor/lib]]
                                        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                        at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
                                        at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
                                        at com.threshold.rxbus2.RxBus.(RxBus.java:79) 
                                        at com.threshold.rxbus2.RxBus.getDefault(RxBus.java:63) 
                                        at com.threshold.rxbus2.RxBus.getInstance(RxBus.java:51) 
                                        at com.threshold.learningdriving.ui.activity.LoginActivity.initRxBusEvent(LoginActivity.java:125) 
                                        at com.threshold.learningdriving.ui.activity.LoginActivity.onResume(LoginActivity.java:148) 
                                        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1269) 
                                        at android.app.Activity.performResume(Activity.java:6783) 
                                        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3406) 
                                        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3469) 
                                        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2732) 
                                        at android.app.ActivityThread.-wrap12(ActivityThread.java) 
                                        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
                                        at android.os.Handler.dispatchMessage(Handler.java:102) 
                                        at android.os.Looper.loop(Looper.java:154) 
                                        at android.app.ActivityThread.main(ActivityThread.java:6119) 
                                        at java.lang.reflect.Method.invoke(Native Method) 
                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

如果还有什么不明白的,请先查看demo看看源码再来留言询问。


RxBus2:基于RxJava2的RxBus_第1张图片
关注我的公众号.jpg

你可能感兴趣的:(RxBus2:基于RxJava2的RxBus)