代碼簡潔,開銷小,並很好的實現了發送者和接收者的解耦.(是一種觀察者模式)
2,三要素:3,通常情況下安卓下數據的傳遞有下面幾種方法:3.1.通過intent傳遞,包括顯式意圖和隱式意圖,廣播(Broadcast)和服務都能通過Intent傳遞
傳遞的數據類型包括8大基本數據類型 實現Parcelable或Serializable接口的類型 以及集合數組類型
3.2.靜態變量傳遞 在工具類下 聲明一個Object類型的靜態變量 在A中將要傳遞的值,在B中通過這個靜態變量取出來
3.3.通過handle在不同的線程中傳遞Object類型的數據
3.4.通過構造方法傳遞Object類型的數據
3.5.通過SharedPreferences傳遞八大基本數據類型
3.6.通過ContentProvider在進程間共享數據
3.7.通過aidl在進程進程傳遞數據
3.8.通過流(本地文件)傳遞八大基本數據類型和實現Serializable接口的數據類型
3.9.通過基類中的屬性或者方法
屬性: 基類公有屬性 在某個子類中賦值 其他子類中都能使用
方法: 子類調用父類的某個方法給父類某個屬性賦值 另外一個子類通過父類的另一個公有方法獲取這個值(這個方法把值返回)
compile 'org.greenrobot:eventbus:3.1.1'
public class MessageEvent {
private String message;
public MessageEvent(String message){
this.message = message;
}
public String getMessage(){
return message;
}
}
EventBus.getDefault().register(this);
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEvent(MessageEvent messageEvent){
Log.e("date","receive it");
Toast.makeText(ViewPageStep1Activity.this, messageEvent.getMessage(), Toast.LENGTH_SHORT).show();
}
EventBus.getDefault().post(new MessageEvent("從fragment將數據傳遞到activity22222222"));
EventBus.getDefault().register(this);
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
@Subscribe(threadMode = ThreadMode.MAIN,stick = true)
public void onEvent(MessageEvent messageEvent){
Log.e("date","receive it");
Toast.makeText(ViewPageStep1Activity.this, messageEvent.getMessage(), Toast.LENGTH_SHORT).show();
}
EventBus.getDefault().postSticky(new MessageEvent("從fragment將數據傳遞到activity22222222"));
如果使用onEvent作為訂閱函數,那麼該事件在哪個線程發布出來的,onEvent就會在這個線程中運行,也就是說發布事件和接收事件線程在同一個線程。使用這個方法時,在onEvent方法中不能執行耗時操作,如果執行耗時操作容易導致事件分發延遲。
onEventMainThread:如果使用onEventMainThread作為訂閱函數,那麼不論事件是在哪個線程中發布出來的,onEventMainThread都會在UI線程中執行,接收事件就會在UI線程中運行,這個在Android中是非常有用的,因為在Android中只能在UI線程中跟新UI,所以在onEvnetMainThread方法中是不能執行耗時操作的。
onEventBackground:如果使用onEventBackgrond作為訂閱函數,那麼如果事件是在UI線程中發布出來的,那麼onEventBackground就會在子線程中運行,如果事件本來就是子線程中發布出來的,那麼onEventBackground函數直接在該子線程中執行。
onEventAsync:使用這個函數作為訂閱函數,那麼無論事件在哪個線程發布,都會創建新的子線程在執行onEventAsync。
(四)源碼解析可以看到,發布者(Publisher)使用post()方法將Event發送到Event Bus,而後Event Bus自動將Event發送到多個訂閱者(Subcriber)。這裡需要注意兩個地方:
(1)一個發布者可以對應多個訂閱者。
(2)3.0以前訂閱者的訂閱方法為onEvent()、onEventMainThread()、onEventBackgroundThread()和onEventAsync()。在Event Bus3.0之後統一採用註解@Subscribe的形式,具體實現方式見下文。
@Subscribe(threadMode = ThreadMode.MAIN)
public void eventBusMain(String str){
Log.i("TAG", "MAIN:"+str+" Thread="+Thread.currentThread().getId());
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void eventBusBg(String str){
Log.i("TAG", "BACKGROUND:"+str+" Thread="+Thread.currentThread().getId());
}
@Subscribe(threadMode = ThreadMode.POSTING)
public void eventBusPosting(String str){
Log.i("TAG", "POSTING:"+str+" Thread="+Thread.currentThread().getId());
}
@Subscribe(threadMode = ThreadMode.ASYNC)
public void eventBusAsync(String str){
Log.i("TAG", "ASYNC:"+str+" Thread="+Thread.currentThread().getId());
}
static volatile EventBus defaultInstance;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
}
2.1,粘性事件,保存到ConCurrenHashMap集合,(在構造方法中實現),
HashMap效率高,但線程不安全,在多線程的情況下,儘量用ConcurrentHashMap,避免多線程並發異常
EventBus(EventBusBuilder builder) {
logger = builder.getLogger();
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadSupport = builder.getMainThreadSupport();
mainThreadPoster = mainThreadSupport != null ? mainThreadSupport.createPoster(this) : null;
backgroundPoster = new BackgroundPoster(this);
asyncPoster = new AsyncPoster(this);
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}
3.1,找到訂閱者的方法.找出傳進來的訂閱者的所有訂閱方法,然後遍歷訂閱者的方法.
A,通過反射來獲取訂閱者中所有的方法,並根據方法的類型,參數和註解找到訂閱方法.
3.2,訂閱者的註冊
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
List<SubscriberMethod> subscriberMethods = subscriberMethodFinder.findSubscriberMethods(subscriberClass);
synchronized (this) {
for (SubscriberMethod subscriberMethod : subscriberMethods) {
subscribe(subscriber, subscriberMethod);
}
}
}
private void findUsingReflectionInSingleClass(FindState findState) {
Method[] methods;
try {
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
,並根據方法的類型,參數和註解找到訂閱方法.
methods = findState.clazz.getMethods();
findState.skipSuperClasses = true;}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
CopyOnWriteArrayList<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions == null) {
subscriptions = new CopyOnWriteArrayList<>();
subscriptionsByEventType.put(eventType, subscriptions);
} else {
if (subscriptions.contains(newSubscription)) {
throw new EventBusException("Subscriber " + subscriber.getClass() + " already registered to event "
+ eventType);
}
}
public void post(Object event) {
PostingThreadState postingState = currentPostingThreadState.get();
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isMainThread = isMainThread();
postingState.isPosting = true;
if (postingState.canceled) {
throw new EventBusException("Internal error. Abort state was not reset");
}
try {
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
public synchronized void unregister(Object subscriber) {
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);
} else { logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass()); }}