android rxbus 一個頁面監聽,Android RxBus的使用

RxBus的核心功能是基于Rxjava的,在RxJava中有個Subject類,它繼承Observable類,同時實現了Observer接口,因此Subject可以同時擔當訂閱者和被訂閱者的角色,這里我們使用Subject的子類PublishSubject來創建一個Subject對象(PublishSubject只有被訂閱后才會把接收到的事件立刻發送給訂閱者),在需要接收事件的地方,訂閱該Subject對象,之后如果Subject對象接收到事件,則會發射給該訂閱者,此時Subject對象充當被訂閱者的角色。完成了訂閱,在需要發送事件的地方將事件發送給之前被訂閱的Subject對象,則此時Subject對象做為訂閱者接收事件,然后會立刻將事件轉發給訂閱該Subject對象的訂閱者,以便訂閱者處理相應事件,到這里就完成了事件的發送與處理。最后就是取消訂閱的操作了,Rxjava中,訂閱操作會返回一個Subscription對象,以便在合適的時機取消訂閱,防止內存泄漏,如果一個類產生多個Subscription對象,我們可以用一個CompositeSubscription存儲起來,以進行批量的取消訂閱。

首先添加類庫

// RxAndroid

compile 'io.reactivex:rxandroid:1.2.1'

// RxJava

compile 'io.reactivex:rxjava:1.2.4'

1、接下來結合實現代碼再做進一步的解釋:

package com.example.rxbus;

import java.util.HashMap;

import rx.Observable;

import rx.Subscription;

import rx.android.schedulers.AndroidSchedulers;

import rx.functions.Action1;

import rx.schedulers.Schedulers;

import rx.subjects.PublishSubject;

import rx.subjects.SerializedSubject;

import rx.subscriptions.CompositeSubscription;

/**

* @author: lijuan

* @description:

* @date: 2017-06-07

* @time: 17:24

*/

public class RxBus {

private static volatile RxBus mInstance;

private SerializedSubject mSubject;

private HashMap mSubscriptionMap;

private RxBus() {

mSubject = new SerializedSubject<>(PublishSubject.create());

}

public static RxBus getInstance() {

if (mInstance == null) {

synchronized (RxBus.class) {

if (mInstance == null) {

mInstance = new RxBus();

}

}

}

return mInstance;

}

/**

* 發送事件

*

* @param o

*/

public void post(Object o) {

mSubject.onNext(o);

}

/**

* 返回指定類型的Observable實例

*

* @param type

* @param

* @return

*/

public Observable tObservable(final Class type) {

return mSubject.ofType(type);

}

/**

* 是否已有觀察者訂閱

*

* @return

*/

public boolean hasObservers() {

return mSubject.hasObservers();

}

/**

* 一個默認的訂閱方法

*

* @param type

* @param next

* @param error

* @param

* @return

*/

public Subscription doSubscribe(Class type, Action1 next, Action1 error) {

return tObservable(type)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(next, error);

}

/**

* 保存訂閱后的subscription

*

* @param o

* @param subscription

*/

public void addSubscription(Object o, Subscription subscription) {

if (mSubscriptionMap == null) {

mSubscriptionMap = new HashMap<>();

}

String key = o.getClass().getName();

if (mSubscriptionMap.get(key) != null) {

mSubscriptionMap.get(key).add(subscription);

} else {

CompositeSubscription compositeSubscription = new CompositeSubscription();

compositeSubscription.add(subscription);

mSubscriptionMap.put(key, compositeSubscription);

}

}

/**

* 取消訂閱

*

* @param o

*/

public void unSubscribe(Object o) {

if (mSubscriptionMap == null) {

return;

}

String key = o.getClass().getName();

if (!mSubscriptionMap.containsKey(key)) {

return;

}

if (mSubscriptionMap.get(key) != null) {

mSubscriptionMap.get(key).unsubscribe();

}

mSubscriptionMap.remove(key);

}

}

先看一下這個私有的構造函數:

private RxBus() {

mSubject = new SerializedSubject<>(PublishSubject.create());

}

由于Subject類是非線程安全的,所以我們通過它的子類SerializedSubject將PublishSubject轉換成一個線程安全的Subject對象。之后可通過單例方法getInstance()進行RxBus的初始化。

在toObservable()根據事件類型,通過mSubject.ofType(type);得到一個Observable對象,讓其它訂閱者來訂閱。其實ofType()方法,會過濾掉不符合條件的事件類型,然后將滿足條件的事件類型通過cast()方法,轉換成對應類型的Observable對象,這點可通過源碼查看。

同時封裝了一個簡單的訂閱方法doSubscribe(),只需要傳入事件類型,相應的回調即可。其實可以根據需求在RxBus中擴展滿足自己需求的doSubscribe()方法,來簡化使用時的代碼邏輯。

在需要發送事件的地方調用post()方法,它間接的通過mSubject.onNext(o);將事件發送給訂閱者。

同時RxBus提供了addSubscription()、unSubscribe()方法,分別來保存訂閱時返回的Subscription對象,以及取消訂閱。

接下我們在具體的場景中測試一下:

1、我們在Activity的onCreate()方法中進行進行訂閱操作:

public static final int SEND = 0x131;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

doSubscribe();

}

/**

* 訂閱事件監聽

*/

public void doSubscribe() {

Subscription subscription = RxBus.getInstance()

.tObservable(NewsModel.class)

.subscribeOn(Schedulers.io())

.observeOn(AndroidSchedulers.mainThread())

.subscribe(new Action1() {

@Override

public void call(NewsModel model) {

switch (model.getStatus()) {

case SEND:

Log.e("rxbus", model.getMsg());

break;

default:

break;

}

}

});

RxBus.getInstance().addSubscription(this, subscription);

}

可以看到我們設定事件類型為NewsModel實體類,當然我們可以設定事件類型為為String或者Integer,并且Subscriber的回調發生在主線程,同時保存了Subscription對象。

2、現在通過一個Button發送事件:

RxBus.getInstance().post(new NewsModel(SEND, "發送一條信息"));

3、最后不要忘了在onDestory()中對廣播進行取消注冊,以及取消訂閱

protected void onDestroy() {

super.onDestroy();

RxBus.getInstance().unSubscribe(this);

}

其它場景有興趣的可自行測試!本篇文章就這樣子啦,存在總結不到位的地方還望指導,感謝_

參考資料:Android 用RxJava模擬一個EventBus ———RxBus

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/272598.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/272598.shtml
英文地址,請注明出處:http://en.pswp.cn/news/272598.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AngularJS $q

updatePushIdfunction($q,pushid) { var d$q.defer(); var data {pushid:pushid}; server.api("/updateRId",data).success(function(res){ if(res.resultcode1){ d.resolve(更新成功.);…

C# 如何轉換生成長整型的時間

這個數字字符串就是我們平常所說的時間戳。什么是時間戳&#xff1f;時間戳&#xff08;timestamp&#xff09;&#xff0c;通常是一個字符序列&#xff0c;唯一地標識某一刻的時間。時間戳是指格林威治時間1970年01月01日00時00分00秒(北京時間1970年01月01日08時00分00秒)起至…

html自動滑動輪播代碼,html+css+js 實現自動滑動輪播圖

輪播圖*{margin: 0 auto;padding: 0;list-style: none; //去圓點}.one {width: 1200px;height:350px;margin: 0 auto;overflow: hidden; //設定好的寬度多余的進行隱藏}.one ul{width: 3600px;position: relative;}.one ul li{float: left; //圖片浮動}.two ul li { …

程序員必定會愛上的10款軟件

目錄 第一款&#xff1a;TrueCrypt 第二款&#xff1a;Soureinsight 第三款&#xff1a;Sublime 第四款&#xff1a;Mindmanager 第五款&#xff1a;MarkdownPad 第六款&#xff1a;Beyond compare 第七款&#xff1a;Vim 第八款&#xff1a;Wireshark 第九款&#xff1a;Fiddl…

html定義字體縱向對齊,HTML5 Canvas的文本如何實現垂直對齊

垂直對齊&#xff0c;使用CSS很容易實現&#xff0c;如果想在HTML5 Canvas中實現垂直對齊&#xff0c;如何設置呢&#xff0c;這就是今天要分享的筆記。HTML畫布垂直對齊的文本&#xff0c;我們可以使用的textBaseline在畫布范圍內的屬性值。textBaseline可以設置以下值之一 &a…

深度學習方法:受限玻爾茲曼機RBM(三)模型求解,Gibbs sampling

歡迎轉載&#xff0c;轉載請注明&#xff1a;本文出自Bin的專欄blog.csdn.net/xbinworld。 技術交流QQ群&#xff1a;433250724&#xff0c;歡迎對算法、技術、應用感興趣的同學加入。 接下來重點講一下RBM模型求解方法&#xff0c;其實用的依然是梯度優化方法&#xff0c;但是…

推薦一款PC端的遠程軟件-Remote Utilities

遠程控制軟件非常之多&#xff0c;但小編自己用過的就那么3個&#xff1a;teamviewer&#xff1a;在家遠程辦公時基本上都靠它連回公司的電腦&#xff0c;速度快、穩定、不需要公網IP。vnc&#xff1a;要開啟vpn才能連回公司的網絡&#xff0c;速度夠快。系統自帶遠程桌面&…

原生js追加html代碼,原生js實現給指定元素的后面追加內容

復制代碼 代碼如下:var header1 document.getElementById("header");var p document.createElement("p"); // 創建一個元素節點insertAfter(p,header1); // 因為js沒有直接追加到指定元素后面的方法 所以要自己創建一個方法function insertAfter( newEle…

這些才是Win10真正好用之處:瞬對Win7無愛

自從將家里的筆電、臺式機全部升級到Win10之后&#xff0c;小編可是切切實實感受到了它的強大&#xff0c;非常多的改進、非常多人性化的設計。和之前的測試版不同&#xff0c;作為主力系統后自然要匹配日常的工作。很多設置、操作也要順應以前的使用習慣。經過這幾天折騰&…

html5 保存 搜索歷史,html5 – 如何有效處理Dart中的瀏覽器歷史記錄(即后退按鈕)?...

HTML5定義了用于操作歷史記錄的新API,允許您在不重新加載窗口的情況下更改位置.有一篇關于Dive Into HTML5的精彩文章,展示了如何使用歷史API在單頁面應用中模擬多頁面導航.它很容易翻譯成Dart.在帶導航的單頁應用程序中,我通常設置客戶端代碼的方式類似于在服務器上設置RoR或D…

多個DataSet數據合并

DataSet ds myIAppSet.GetHomeHottestList(siteID, 0, time); DataSet ds1 myIAppSet.GetHomeHottestList(siteID, 1, time);if (ds1 ! null && ds1.Tables[0].Rows.Count > 0){ds.Merge(ds1);} Merge方法&#xff0c;用于DataSet、DataTable&#xff0c;多個字段…

math.js:靈活強大的JavaScript數學庫

最近為期權開發一些基本技術指標&#xff0c;用到一些C的數學庫&#xff0c;剛好看到JavaScript的math.js庫&#xff0c;這里對math.js做一下簡單介紹。一、什么是math.jsmath.js是一個廣泛應用于JavaScript 和 Node.js的數學庫&#xff0c;它的特點是靈活表達式解析器&#xf…

html的閃爍字,HTML最簡單的文字閃爍代碼

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓Titlekeyframes blink{0%{opacity: 1;}50%{opacity: 1;}50.01%{opacity: 0;}100%{opacity: 0;}}-webkit-keyframes blink {0% { opacity: 1; }50% { opacity: 1; }50.01% { opacity: 0; }100% { opacity: 0; }}-moz-keyframes blin…

video和dvd audio區別:

VIDEO 是視頻&#xff0c;AUDIO是音頻。DVD- Audio 是目前流行的DVD光碟格式的一種擴展&#xff0c;區別在于它能夠傳輸先前所有音頻載體格式無法攜帶的全新標準的高質量音頻數據。最引人注目的特點是它多聲道音頻的能力。轉載于:https://www.cnblogs.com/zjqqqq/p/5060931.htm…

Win10非常好用的6個使用技巧

很多人已經用上了Win10系統&#xff0c;為了提高使用效率掌握使用技巧尤為重要&#xff0c;今天我為大家分享win10的6個使用技巧。第一個&#xff1a;快速查找文件&#xff08;win鍵E&#xff09;想要打開某個文件&#xff0c;直接使用這個快捷鍵就可以打開資源管理器&#xff…

servlet html登錄,Servlet實現用戶登錄

1、登錄過程分析&#xff1a;通過表單收集用戶的數據&#xff0c;Servlet通過request對象獲得用戶提交的數據&#xff0c;服務器還需要從數據庫中通過sql語句查詢有沒有表單提交的數據中的用戶。有則登錄成功&#xff0c;否則&#xff0c;登錄失敗。2、工程結構&#xff1a;3、…

HTML5拖放API

HTML5拖放API 拖放事件 HTML5拖放API 拖放事件事件提供了拖放可以控制幾乎所有方面的拖放操作。棘手的部分是確定每個事件觸發&#xff1a;在拖項目火&#xff1b;別人火下降的目標。 拖動項時&#xff0c;以下事件&#xff08;按照這個順序&#xff09;&#xff1a;拖曳開始拖…

C#easyui combotree 設置節點折疊

樹實體public class Combotree{public string id { get; set; }public string text { get; set; }public string state { get; set; }public List<Combotree> children { get; set; }} 只需要在初始化數據的時候給state 設置為 closed注意&#xff1a;不要在最后一級節點…

用于大型的科學計算的計算機,科學計算器廣泛適用于大、中、小學生、教師、科研人員及其他各界...

科學計算器廣泛適用于大、中、小學生、教師、科研人員及其他各界人士。相關句子1、機器人廣泛應用于弧焊&#xff0c;點焊&#xff0c;涂膠&#xff0c;切割&#xff0c;搬運&#xff0c;碼垛&#xff0c;噴漆&#xff0c;科研及教學。3、可以滿足大學本科和研究生有關實驗課教…

C#中AssemblyInfo.cs文件詳解

1、.Net工程的Properties文件夾下自動生成一個名為AssemblyInfo.cs的文件&#xff0c;一般情況下我們很少直接改動該文件。但我們實際上通過另一個形式操作該文件。那就是通過在鼠標右鍵點擊項目的屬性進入“應用程序”->“程序集信息”&#xff0c;然后修改信息。2、通過特…