Android事件通知工具:RxBus在Eclipse和AS中的实践

简介: Android事件通知工具:RxBus在Eclipse和AS中的实践

相信大家在进行Android开发的时候最头疼的就是这边有一个点击事件,需要传递到其他界面显示结果,或者说有一处变化了需要告诉许多界面去刷新界面。相信经常使用Fragment进行开发的小伙伴们经常会遇到Fragment界面相互影响,相互刷新的各种负责的业务。这些都是我们需要使用到事件通知的场景。


最初我们使用的是Android自身携带的广播Broadcast来解决这个问题,在需要接收的地方注册广播接收监听,然后通过context.sendBroadcast来发送事件,通过Intent来传递数据。这种如果在最初使用的话还是比较简单的,但是如果需要通知的事件多了的话,整个项目里面就都是sendBroadcast以及registerReceiver,广播使用得不好还很容易出现内存泄露,代码的逻辑性以及程序的稳定性将会大打折扣,使用起来也是极其不方便。


后来学习了java的设计模式之观察者模式,自己设计了一套事件通知工具,其实质还是“接口回调监听“,使用起来可以说比广播好了多了,但是嘛,在使用的过程中还是会出现这些或者那些的问题,最主要的问题就是接口回调不能给自由地切换线程,在子线程回调出来的就是子线程,在主线程回调出来的就是主线程,不好进行线程控制。这也是为什么之前EventBus事件工具如此火的原因所在,它可以控制事件触发的子线程还是主线程。


但是仅仅是EventBus根本满足不了我对代码简洁、使用方便、安全的要求。我理想中的事件工具应该是这样的:只需一行代码就可以完成事件动作的注册、只需一行代码就可以完成事件的传递、只需一行代码就可以轻松地注销事件监听,并且可以自由地控制线程,而串联这三个的只需要一个事件TAG即可,后面只需要维护这个事件TAG就行了。不需要像EventBus那样在每个Activity或者Fragment里面写onEventMainThread这种笨笨的代码。那么这样的事件工具真的有吗?当然有啦,那就是接下来我要隆重地推荐以及介绍的RxBus!


RxBus顾名思义是基于RxJava这个目前火得不能再火的项目改造而成的,RxBus继承了RxJava的最大特性:变化【转化】,通过它我们可以轻松地进行线程控制,代码也起来也是极其简洁明了。RxBus的代码很简洁,只有一个java类,如下:


/**
 * RxBus
 * 
 * @author xx
 * 
 */
public class RxBus {
  private ConcurrentHashMap<Object, List> maps = new ConcurrentHashMap<Object, List>();
  private static RxBus sInstance;
  public static RxBus get() {
    if (sInstance == null) {
      synchronized (RxBus.class) {
        if (sInstance == null) {
          sInstance = new RxBus();
        }
      }
    }
    return sInstance;
  }
  /**
   * 简单以对象的类名注册
   * @param o
   * @return
   */
  public  Observable simpleRegister(@NonNull Object o) {
    return register(o.getClass().getSimpleName());
  }
  /**
   * 注册订阅
   * @param tag
   * @return
   */
  public  Observable register(@NonNull Object tag) {
    List subjects = maps.get(tag);
    if (subjects == null) {
      subjects = new ArrayList();
      maps.put(tag, subjects);
    }
    Subject subject = PublishSubject. create();
    subjects.add(subject);
    return subject;
  }
  /**
   * 注销tag制定的订阅
   * @param tag
   */
  public void unregister(@NonNull Object tag, @NonNull Observable observable) {
    List subjects = maps.get(tag);
    if (subjects != null) {
      subjects.remove((Subject) observable);
      if (subjects.isEmpty()) {
        maps.remove(tag);
      }
    }
  }
  /**
   * 注销tag所有的订阅
   * @param tag
   */
  public void unregisterAll(@NonNull Object tag) {
    List subjects = maps.get(tag);
    if (subjects != null) {
      maps.remove(tag);
    }
  }
  public void post(@NonNull Object tag) {
    post(tag, tag);
  }
  /**
   * 发送指定tag的事件
   * @param tag
   * @param o
   */
  @SuppressWarnings("unchecked")
  public void post(@NonNull Object tag, @NonNull Object o) {
    List subjects = maps.get(tag);
    if (subjects != null && !subjects.isEmpty()) {
      for (Subject s : subjects) {
        s.onNext(o);
      }
    }
  }
}
public class RxManager {
  private final static String TAG = "RxManager";
  private static RxManager sInstance;
  private RxBus mRxBus = RxBus.get();
  /** 管理Subscribers订阅,防止内存泄漏 */
  private ConcurrentHashMap maps = new ConcurrentHashMap();
  public static RxManager get() {
    if (sInstance == null) {
      synchronized (RxManager.class) {
        if (sInstance == null) {
          sInstance = new RxManager();
        }
      }
    }
    return sInstance;
  }
  /**
   * 
   * RxBus注入监听
   * 
   * @param eventName
   * 
   * @param action1
   */
  public  void onMainThread(Object eventName, Action1 action1) {
    Observable Observable = mRxBus.register(eventName);
    /* 订阅管理 */
    add(eventName, Observable.observeOn(AndroidSchedulers.mainThread()).subscribe(action1, new Action1() {
      @Override
      public void call(Throwable throwable) {
        Log.e(TAG, throwable.getMessage());
      }
    }));
  }
  /**
   * 
   * RxBus注入监听
   * 
   * @param eventName
   *            事件名
   * @param action1
   */
  public  void on(Object eventName, Action1 action1) {
    Observable Observable = mRxBus.register(eventName);
    /* 订阅管理 */
    add(eventName, Observable.subscribe(action1, new Action1() {
      @Override
      public void call(Throwable throwable) {
        Log.e(TAG, throwable.getMessage());
      }
    }));
  }
  /**
   * 单纯的Observables 和Subscribers管理
   * 
   * @param m
   */
  public void add(Object eventName, Subscription m) {
    /* 订阅管理 */
    CompositeSubscription subscription = maps.get(eventName);
    if (subscription == null) {
      subscription = new CompositeSubscription();
      maps.put(eventName, subscription);
    }
    subscription.add(m);
  }
  /**
   * 
   * 单个presenter生命周期结束,取消订阅和所有rxbus观察
   */
  public void clear(@NonNull Object eventName) {
    CompositeSubscription subscription = maps.get(eventName);
    if (subscription != null) {
      subscription.unsubscribe(); // 取消订阅
      maps.remove(eventName);
    }
    mRxBus.unregisterAll(eventName);
  }
  // 发送rxbus
  public void post(Object tag) {
    mRxBus.post(tag);
  }
  // 发送rxbus
  public void post(Object tag, Object content) {
    mRxBus.post(tag, content);
  }
}


这里我就不具体阐述RxBus以及RxManager是如何起到事件通知的效果的,想了解的可以自行去了解Rxjava的特性。


这里我只介绍如何使用RxBus。


1、首先是事件动作注册:


RxManager.get().on注册的事件回调后返回的还是当前的线程,RxManager.get().onMainThread注册的事件回调后返回的直接是主线程。


20170518152120374.png


2、其次是事件的通知:


直接调用RxManager.get().post(Event_Key) :不携带数据的事件


RxManager.get().post(Event_Key,object) :携带数据的事件


20170518152611292.png


3、最后就是事件监听的销毁:


直接调用RxManager.get().clear(Event_Key)即可。


20170518152840978.png


以上三部即可完成事件通知的全过程,是不是很方便啊,O(∩_∩)O~~,实在是太给力了!


相关文章
|
2月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
3月前
|
安全 Android开发 Kotlin
Android经典实战之SurfaceView原理和实践
本文介绍了 `SurfaceView` 这一强大的 UI 组件,尤其适合高性能绘制任务,如视频播放和游戏。文章详细讲解了 `SurfaceView` 的原理、与 `Surface` 类的关系及其实现示例,并强调了使用时需注意的线程安全、生命周期管理和性能优化等问题。
177 8
|
17天前
|
搜索推荐 Android开发 开发者
安卓应用开发中的自定义控件实践
在安卓应用开发的广阔天地中,自定义控件如同璀璨的星辰,点亮了用户界面设计的夜空。它们不仅丰富了交互体验,更赋予了应用独特的个性。本文将带你领略自定义控件的魅力,从基础概念到实际应用,一步步揭示其背后的原理与技术细节。我们将通过一个简单的例子——打造一个具有独特动画效果的按钮,来展现自定义控件的强大功能和灵活性。无论你是初学者还是资深开发者,这篇文章都将为你打开一扇通往更高阶UI设计的大门。
|
22天前
|
NoSQL 编译器 C语言
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。
C语言调试是开发中的重要技能,涵盖基本技巧如打印输出、断点调试和单步执行,以及使用GCC、GDB、Visual Studio和Eclipse CDT等工具。高级技巧包括内存检查、性能分析和符号调试。通过实践案例学习如何有效定位和解决问题,同时注意保持耐心、合理利用工具、记录过程并避免过度调试,以提高编程能力和开发效率。
37 1
|
29天前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
47 8
|
2月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
45 1
|
1月前
|
前端开发 Android开发 UED
安卓应用开发中的自定义控件实践
【10月更文挑战第35天】在移动应用开发中,自定义控件是提升用户体验、增强界面表现力的重要手段。本文将通过一个安卓自定义控件的创建过程,展示如何从零开始构建一个具有交互功能的自定义视图。我们将探索关键概念和步骤,包括继承View类、处理测量与布局、绘制以及事件处理。最终,我们将实现一个简单的圆形进度条,并分析其性能优化。
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android 事件分发机制详细解读
Android 事件分发机制详细解读
44 5

推荐镜像

更多
下一篇
DataWorks