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~~,实在是太给力了!


相关文章
|
25天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
2月前
|
安全 Android开发 Kotlin
Android经典实战之SurfaceView原理和实践
本文介绍了 `SurfaceView` 这一强大的 UI 组件,尤其适合高性能绘制任务,如视频播放和游戏。文章详细讲解了 `SurfaceView` 的原理、与 `Surface` 类的关系及其实现示例,并强调了使用时需注意的线程安全、生命周期管理和性能优化等问题。
142 8
|
9天前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
13天前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
26 1
|
18天前
|
XML 前端开发 Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
25天前
|
Android开发
Android 事件分发机制详细解读
Android 事件分发机制详细解读
36 4
|
25天前
|
前端开发 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的世界里,自定义控件如同画家的画笔,能够绘制出独一无二的界面。通过掌握自定义控件的绘制技巧,开发者可以突破系统提供的界面元素限制,创造出既符合品牌形象又提供卓越用户体验的应用。本文将引导你了解自定义控件的核心概念,并通过一个简单的例子展示如何实现一个基本的自定义控件,让你的安卓应用在视觉和交互上与众不同。
|
1月前
|
测试技术 数据库 Android开发
深入解析Android架构组件——Jetpack的使用与实践
本文旨在探讨谷歌推出的Android架构组件——Jetpack,在现代Android开发中的应用。Jetpack作为一系列库和工具的集合,旨在帮助开发者更轻松地编写出健壮、可维护且性能优异的应用。通过详细解析各个组件如Lifecycle、ViewModel、LiveData等,我们将了解其原理和使用场景,并结合实例展示如何在实际项目中应用这些组件,提升开发效率和应用质量。
38 6
|
2月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
114 3
|
2月前
|
缓存 搜索推荐 Android开发
安卓应用开发中的自定义View组件实践
【9月更文挑战第10天】在安卓开发领域,自定义View是提升用户体验和实现界面个性化的重要手段。本文将通过一个实际案例,展示如何在安卓项目中创建和使用自定义View组件,包括设计思路、实现步骤以及可能遇到的问题和解决方案。文章不仅提供了代码示例,还深入探讨了自定义View的性能优化技巧,旨在帮助开发者更好地掌握这一技能。

推荐镜像

更多