要實現fragment與activity之前的通訊,或者service與activity的通訊,我們可以有好幾種方式實現
1、廣播
2、回調接口
3、eventBus、RxBus
4、其他
封裝了一下RxBus的使用,廢話不多說,直接上源碼:
1、ThreadMode,所執行的線程
public enum ThreadMode {
/**
* current thread
*/
CURRENT_THREAD,
/**
* android main thread
*/
MAIN,
/**
* new thread
*/
NEW_THREAD
}
2、Subscribe,註解
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Subscribe {
int code() default -1;
ThreadMode threadMode() default ThreadMode.CURRENT_THREAD;
}
3、SubscriberMethod,存儲訂閱者的相關信息,並提供invoke調用
public class SubscriberMethod {
public Method method;
public ThreadMode threadMode;
public Class<?> eventType;
public Object subscriber;
public int code;
public boolean originalIsPrimitive;//原始類型是否爲基本類型
public SubscriberMethod(Object subscriber, Method method, Class<?> eventType, int code, ThreadMode threadMode, boolean originalIsPrimitive) {
this.method = method;
this.threadMode = threadMode;
this.eventType = eventType;
this.subscriber = subscriber;
this.code = code;
this.originalIsPrimitive = originalIsPrimitive;
}
/**
* 調用方法
*
* @param o 參數
*/
public void invoke(Object o) {
try {
Class[] parameterType = method.getParameterTypes();
if (parameterType != null && parameterType.length == 1) {
method.invoke(subscriber, o);
} else if (parameterType == null || parameterType.length == 0) {
method.invoke(subscriber);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
4、PrimitiveBox,基本類型轉換成對象類型
public class PrimitiveBox {
/**
* 裝箱
*
* @param target 目標類
* @return 轉換後的Class
*/
public static Class<?> mantle(final Class<?> target) {
if (boolean.class.equals(target)) {
return Boolean.class;
} else if (char.class.equals(target)) {
return Character.class;
} else if (byte.class.equals(target)) {
return Byte.class;
} else if (short.class.equals(target)) {
return Short.class;
} else if (int.class.equals(target)) {
return Integer.class;
} else if (long.class.equals(target)) {
return Long.class;
} else if (float.class.equals(target)) {
return Float.class;
} else if (double.class.equals(target)) {
return Double.class;
} else {
return target;
}
}
}
5、BusData,默認的事件類型
public class BusData {
String id;
String status;
public BusData() {}
public BusData(String id, String status) {
this.id = id;
this.status = status;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
6、RxBus,核心類
public class RxBus {
public static final String TAG = "RxBus_log";
private static volatile RxBus defaultInstance;
/**
* key==》訂閱者對象,value==》訂閱事件(disposable )
*/
private Map<Object, List<Disposable>> subscriptionsByEventType = new HashMap<>();
/**
* key==》訂閱者對象,value==》事件類型
* <p>
* value是 根據Key所註解的方法的參數類型確定,默認==》BusData,如:
* <p>
* 註解方法==》a(),則value==》BusData
* 註解方法==》a(String str),則value==》String
*/
private Map<Object, List<Class>> eventTypesBySubscriber = new HashMap<>();
/**
* key==》事件類型,value==》訂閱者信息
* <p>
* value信息包括:訂閱者對象(subscriber), 方法名(method), 事件類型(eventType), 事件code(code), 線程類型(threadMode)
*/
private Map<Class, List<SubscriberMethod>> subscriberMethodByEventType = new HashMap<>();
private final Subject<Object> bus;
private RxBus() {
this.bus = PublishSubject.create().toSerialized();
}
public static RxBus getDefault() {
RxBus rxBus = defaultInstance;
if (defaultInstance == null) {
synchronized (RxBus.class) {
rxBus = defaultInstance;
if (defaultInstance == null) {
rxBus = new RxBus();
defaultInstance = rxBus;
}
}
}
return rxBus;
}
/**
* 註冊
*
* @param subscriber 訂閱者
*/
public void register(Object subscriber) {
YLogUtil.logD2Tag(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@註冊@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@--訂閱者對象", subscriber);
//根據對象獲取類
Class<?> subClass = subscriber.getClass();
//獲取所有方法名
Method[] methods = subClass.getDeclaredMethods();
for (Method method : methods) {
//判斷方法是否存在註解
if (method.isAnnotationPresent(Subscribe.class)) {
//獲得參數類型
Class[] parameterType = method.getParameterTypes();
//參數不爲空 且參數個數爲1
if (parameterType != null && parameterType.length == 1) {
Class eventType = parameterType[0];
executeRegistered(subscriber, method, eventType);
} else if (parameterType == null || parameterType.length == 0) {
Class eventType = BusData.class;
executeRegistered(subscriber, method, eventType);
}
}
}
YLogUtil.logD2Tag(TAG, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@註冊完成@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@--訂閱者對象", subscriber);
}
/**
* 取消註冊
*
* @param subscriber 訂閱者
*/
public void unregister(Object subscriber) {
YLogUtil.logD2Tag(TAG, "###################################取消註冊###################################--訂閱者對象", subscriber);
//通過訂閱者對象,獲取對應的事件類型集合
List<Class> subscribedTypes = eventTypesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
unSubscribeByEventType(subscriber);
unSubscribeMethodByEventType(subscriber, eventType);
YLogUtil.logD2Tag(TAG, "執行取消註冊--訂閱者對象", subscriber, "事件類型", eventType);
}
eventTypesBySubscriber.remove(subscriber);
}
YLogUtil.logD2Tag(TAG, "###################################取消註冊完成###############################--訂閱者對象", subscriber);
}
/**
* 是否註冊
*
* @param subscriber 訂閱者
* @return
*/
public synchronized boolean isRegistered(Object subscriber) {
boolean isRegistered = eventTypesBySubscriber.containsKey(subscriber);
YLogUtil.logD2Tag(TAG, "************************************判斷是否註冊******************************--訂閱者對象", subscriber, "是?", isRegistered);
return isRegistered;
}
/**
* 執行註冊
*
* @param subscriber 訂閱者對象
* @param method 方法名
* @param eventType 事件類型
*/
private void executeRegistered(Object subscriber, Method method, Class eventType) {
//判斷是否爲基本類型
boolean isPrimitive = eventType.isPrimitive();
if (isPrimitive) {
YLogUtil.logD2Tag(TAG, "*********基礎類型自動裝箱---開始*********裝箱前類型", eventType);
eventType = PrimitiveBox.mantle(eventType);
YLogUtil.logD2Tag(TAG, "*********基礎類型自動裝箱---完成*********裝箱後類型", eventType);
}
// key==》訂閱者對象,value==》事件類型,保存到map裏
addEventTypeToMap(subscriber, eventType);
//獲取註解
Subscribe sub = method.getAnnotation(Subscribe.class);
int code = sub.code();
ThreadMode threadMode = sub.threadMode();
//key==》事件類型,value==》訂閱者信息,保存到map裏
SubscriberMethod subscriberMethod = new SubscriberMethod(subscriber, method, eventType, code, threadMode, isPrimitive);
addSubscriberToMap(eventType, subscriberMethod);
//添加到RxJava訂閱
addSubscriber(subscriberMethod);
YLogUtil.logD2Tag(TAG, "執行註冊---方法:", method, "---事件類型:", eventType);
}
/**
* key==》訂閱者對象,value==》事件類型,保存到map裏
*
* @param subscriber 訂閱者對象
* @param eventType 事件類型
*/
private void addEventTypeToMap(Object subscriber, Class eventType) {
List<Class> eventTypes = eventTypesBySubscriber.get(subscriber);
if (eventTypes == null) {
eventTypes = new ArrayList<>();
eventTypesBySubscriber.put(subscriber, eventTypes);
}
if (!eventTypes.contains(eventType)) {
eventTypes.add(eventType);
}
}
/**
* key==》事件類型,value==》訂閱者信息,保存到map裏
*
* @param eventType 事件類型
* @param subscriberMethod 訂閱者信息
*/
private void addSubscriberToMap(Class eventType, SubscriberMethod subscriberMethod) {
List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType);
if (subscriberMethods == null) {
subscriberMethods = new ArrayList<>();
subscriberMethodByEventType.put(eventType, subscriberMethods);
}
if (!subscriberMethods.contains(subscriberMethod)) {
subscriberMethods.add(subscriberMethod);
}
}
/**
* 用RxJava添加訂閱者
*
* @param subscriberMethod 訂閱者信息
*/
@SuppressWarnings("unchecked")
private void addSubscriber(final SubscriberMethod subscriberMethod) {
Flowable flowable;
if (subscriberMethod.code == -1) {
flowable = toObservable(subscriberMethod.eventType);
} else {
flowable = toObservable(subscriberMethod.code, subscriberMethod.eventType);
}
Disposable subscription = postToObservable(flowable, subscriberMethod)
.subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
callEvent(subscriberMethod, o);
}
});
//key==》訂閱者對象,value==》訂閱事件(disposable )
addSubscriptionToMap(subscriberMethod.subscriber, subscription);
}
/**
* 根據傳遞的 eventType 類型返回特定類型(eventType)的 被觀察者
*
* @param eventType 事件類型
* @return return
*/
public <T> Flowable<T> toObservable(Class<T> eventType) {
//ofType(class) 指定某個類型的class,過濾屬於這個類型的的結果,其它拋棄
return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(eventType);
}
/**
* 根據傳遞的code和 eventType 類型返回特定類型(eventType)的 被觀察者
*
* @param code 事件code
* @param eventType 事件類型
*/
private <T> Flowable<T> toObservable(final int code, final Class<T> eventType) {
//ofType(class) 指定某個類型的class,過濾屬於這個類型的的結果,其它拋棄
return bus.toFlowable(BackpressureStrategy.BUFFER).ofType(Message.class)
//採用filter()變換操作符
.filter(new Predicate<Message>() {
// 根據test()的返回值 對被觀察者發送的事件進行過濾 & 篩選
// a. 返回true,則繼續發送
// b. 返回false,則不發送(即過濾)
@Override
public boolean test(Message o) throws Exception {
return o.getCode() == code && eventType.isInstance(o.getObject());
}
// map操作符,Function<Object,Object>,只要類型爲Object的子類就可以進行轉換
}).map(new Function<Message, Object>() {
@Override
public Object apply(Message o) throws Exception {
return o.getObject();
}
}).cast(eventType);
}
/**
* 用於處理訂閱事件在那個線程中執行
*
* @param observable 訂閱事件
* @param subscriberMethod 訂閱者信息
* @return Observable
*/
private Flowable postToObservable(Flowable observable, SubscriberMethod subscriberMethod) {
Scheduler scheduler;
switch (subscriberMethod.threadMode) {
case MAIN:
scheduler = AndroidSchedulers.mainThread();
break;
case NEW_THREAD:
scheduler = Schedulers.newThread();
break;
case CURRENT_THREAD:
scheduler = Schedulers.trampoline();
break;
default:
throw new IllegalStateException("Unknown thread mode: " + subscriberMethod.threadMode);
}
return observable.observeOn(scheduler);
}
/**
* key==》訂閱者對象,value==》訂閱事件(disposable )
*
* @param subscriber 訂閱者對象
* @param disposable 訂閱事件
*/
private void addSubscriptionToMap(Object subscriber, Disposable disposable) {
List<Disposable> disposables = subscriptionsByEventType.get(subscriber);
if (disposables == null) {
disposables = new ArrayList<>();
subscriptionsByEventType.put(subscriber, disposables);
}
if (!disposables.contains(disposable)) {
disposables.add(disposable);
}
}
/**
* 回調到訂閱者的方法中
*
* @param subscriberMethod 訂閱者信息
* @param object 事件類型對象
*/
private void callEvent(SubscriberMethod subscriberMethod, Object object) {
YLogUtil.logD2Tag(TAG, "執行回調----訂閱者對象", subscriberMethod.subscriber, "方法", subscriberMethod.method, "事件類型對象", object);
//因爲最終發送的爲事件類型對象
//所以需要通過事件類型對象,獲取對應的事件類型
Class eventClass = object.getClass();
//通過事件類型,獲取訂閱者信息
List<SubscriberMethod> subscriberMethodList = subscriberMethodByEventType.get(eventClass);
//判斷訂閱者信息是否相同,並回調訂閱者
if (subscriberMethodList != null && subscriberMethodList.size() > 0) {
for (SubscriberMethod tmpSubscriberMethod : subscriberMethodList) {
if (tmpSubscriberMethod.code == subscriberMethod.code && subscriberMethod.subscriber.equals(tmpSubscriberMethod.subscriber)
&& subscriberMethod.method.equals(tmpSubscriberMethod.method)) {
tmpSubscriberMethod.invoke(object);
YLogUtil.logD2Tag(TAG, "回調成功----訂閱者對象", subscriberMethod.subscriber, "方法", subscriberMethod.method, "事件類型對象", object);
}
}
}
}
/**
* 移除訂閱者對象對應的訂閱事件
*
* @param subscriber 訂閱者對象
*/
private void unSubscribeByEventType(Object subscriber) {
List<Disposable> disposables = subscriptionsByEventType.get(subscriber);
if (disposables != null) {
Iterator<Disposable> iterator = disposables.iterator();
while (iterator.hasNext()) {
Disposable disposable = iterator.next();
if (disposable != null && !disposable.isDisposed()) {
disposable.dispose();
iterator.remove();
}
}
}
}
/**
* 移除訂閱者對象對應的訂閱者信息
*
* @param subscriber 訂閱者對象
* @param eventType 事件類型
*/
private void unSubscribeMethodByEventType(Object subscriber, Class eventType) {
//通過事件類型,獲取訂閱者信息
List<SubscriberMethod> subscriberMethods = subscriberMethodByEventType.get(eventType);
//判斷訂閱者信息的訂閱者對象是否相同
if (subscriberMethods != null) {
Iterator<SubscriberMethod> iterator = subscriberMethods.iterator();
while (iterator.hasNext()) {
SubscriberMethod subscriberMethod = iterator.next();
if (subscriberMethod.subscriber.equals(subscriber)) {
iterator.remove();
}
}
}
}
public void send(int code, Object o) {
Message message = new Message(code, o);
bus.onNext(message);
YLogUtil.logD2Tag(TAG, "發送RxBus", o);
}
public void post(Object o) {
bus.onNext(o);
}
public void send(int code) {
Message message = new Message(code, new BusData());
bus.onNext(message);
YLogUtil.logD2Tag(TAG, "發送RxBus", message.object);
}
private class Message {
private int code;
private Object object;
public Message() {
}
private Message(int code, Object o) {
this.code = code;
this.object = o;
}
private int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
private Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
}
}
RxBus使用方式
一、註冊RxBus:
public class TestActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RxBus.getDefault().register(this);
}
@SuppressLint("測試1,參數爲String類型")
@Subscribe(code = 1001, threadMode = ThreadMode.MAIN)
public void rxBusTest1(String msg) {
}
@SuppressLint("測試2,參數爲int基本數據類型")
@Subscribe(code = 1002, threadMode = ThreadMode.MAIN)
public void rxBusTest2(int type) {
}
@SuppressLint("測試3,參數爲自定義對象")
@Subscribe(code = 1003, threadMode = ThreadMode.MAIN)
public void rxBusTest3(MsgData msgData) {
}
@SuppressLint("測試4,無參")
@Subscribe(code = 1004, threadMode = ThreadMode.MAIN)
public void rxBusTest4() {
}
@Override
protected void onDestroy() {
super.onDestroy();
RxBus.getDefault().unregister(this);
}
}
二、發送RxBus:
RxBus.getDefault().send(1001,"hihi");
RxBus.getDefault().send(1002,123);
RxBus.getDefault().send(1003,new MsgData(111,"test"));
RxBus.getDefault().send(1004);
public class MsgData {
public int code;
public String msg;
public MsgData (int code, String msg) {
this.code = code;
this.msg = msg;
}
}
混淆:
#如RxBus所在包名爲com.cn.rxbus
#Rxbus混淆
-dontwarn com.cn.rxbus.**
-keep class com.cn.rxbus.** { *;}
-keepattributes *Annotation
-keep @com.cn.rxbus.Subscribe class * {*;}
-keep class * {
@com.cn.rxbus.Subscribe <fields>;
}
-keepclassmembers class * {
@com.cn.rxbus.Subscribe <methods>;
}
#Rxbus混淆end