subscriberInfoIndexes;
+ Logger logger;
+ MainThreadSupport mainThreadSupport;
EventBusBuilder() {
}
@@ -83,7 +86,7 @@ public EventBusBuilder throwSubscriberException(boolean throwSubscriberException
* By default, EventBus considers the event class hierarchy (subscribers to super classes will be notified).
* Switching this feature off will improve posting of events. For simple event classes extending Object directly,
* we measured a speed up of 20% for event posting. For more complex event hierarchies, the speed up should be
- * >20%.
+ * greater than 20%.
*
* However, keep in mind that event posting usually consumes just a small proportion of CPU time inside an app,
* unless it is posting at high rates, e.g. hundreds/thousands of events per second.
@@ -130,13 +133,41 @@ public EventBusBuilder strictMethodVerification(boolean strictMethodVerification
/** Adds an index generated by EventBus' annotation preprocessor. */
public EventBusBuilder addIndex(SubscriberInfoIndex index) {
- if(subscriberInfoIndexes == null) {
+ if (subscriberInfoIndexes == null) {
subscriberInfoIndexes = new ArrayList<>();
}
subscriberInfoIndexes.add(index);
return this;
}
+ /**
+ * Set a specific log handler for all EventBus logging.
+ *
+ * By default, all logging is via {@code android.util.Log} on Android or System.out on JVM.
+ */
+ public EventBusBuilder logger(Logger logger) {
+ this.logger = logger;
+ return this;
+ }
+
+ Logger getLogger() {
+ if (logger != null) {
+ return logger;
+ } else {
+ return Logger.Default.get();
+ }
+ }
+
+ MainThreadSupport getMainThreadSupport() {
+ if (mainThreadSupport != null) {
+ return mainThreadSupport;
+ } else if (AndroidComponents.areAvailable()) {
+ return AndroidComponents.get().defaultMainThreadSupport;
+ } else {
+ return null;
+ }
+ }
+
/**
* Installs the default EventBus returned by {@link EventBus#getDefault()} using this builders' values. Must be
* done only once before the first usage of the default EventBus.
diff --git a/EventBus/src/org/greenrobot/eventbus/Logger.java b/EventBus/src/org/greenrobot/eventbus/Logger.java
new file mode 100644
index 00000000..e9ec8e88
--- /dev/null
+++ b/EventBus/src/org/greenrobot/eventbus/Logger.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012-2020 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+import org.greenrobot.eventbus.android.AndroidComponents;
+import java.util.logging.Level;
+
+public interface Logger {
+
+ void log(Level level, String msg);
+
+ void log(Level level, String msg, Throwable th);
+
+ class JavaLogger implements Logger {
+ protected final java.util.logging.Logger logger;
+
+ public JavaLogger(String tag) {
+ logger = java.util.logging.Logger.getLogger(tag);
+ }
+
+ @Override
+ public void log(Level level, String msg) {
+ // TODO Replace logged method with caller method
+ logger.log(level, msg);
+ }
+
+ @Override
+ public void log(Level level, String msg, Throwable th) {
+ // TODO Replace logged method with caller method
+ logger.log(level, msg, th);
+ }
+
+ }
+
+ class SystemOutLogger implements Logger {
+
+ @Override
+ public void log(Level level, String msg) {
+ System.out.println("[" + level + "] " + msg);
+ }
+
+ @Override
+ public void log(Level level, String msg, Throwable th) {
+ System.out.println("[" + level + "] " + msg);
+ th.printStackTrace(System.out);
+ }
+
+ }
+
+ class Default {
+ public static Logger get() {
+ if (AndroidComponents.areAvailable()) {
+ return AndroidComponents.get().logger;
+ }
+
+ return new SystemOutLogger();
+ }
+ }
+
+}
diff --git a/EventBus/src/org/greenrobot/eventbus/MainThreadSupport.java b/EventBus/src/org/greenrobot/eventbus/MainThreadSupport.java
new file mode 100644
index 00000000..22605811
--- /dev/null
+++ b/EventBus/src/org/greenrobot/eventbus/MainThreadSupport.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+/**
+ * Interface to the "main" thread, which can be whatever you like. Typically on Android, Android's main thread is used.
+ */
+public interface MainThreadSupport {
+
+ boolean isMainThread();
+
+ Poster createPoster(EventBus eventBus);
+}
diff --git a/EventBus/src/org/greenrobot/eventbus/Poster.java b/EventBus/src/org/greenrobot/eventbus/Poster.java
new file mode 100644
index 00000000..67cfd67c
--- /dev/null
+++ b/EventBus/src/org/greenrobot/eventbus/Poster.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+/**
+ * Posts events.
+ *
+ * @author William Ferguson
+ */
+public interface Poster {
+
+ /**
+ * Enqueue an event to be posted for a particular subscription.
+ *
+ * @param subscription Subscription which will receive the event.
+ * @param event Event that will be posted to subscribers.
+ */
+ void enqueue(Subscription subscription, Object event);
+}
diff --git a/EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java b/EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java
index db5e0ad3..3f2812bc 100644
--- a/EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java
+++ b/EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java
@@ -154,7 +154,17 @@ private void findUsingReflectionInSingleClass(FindState findState) {
methods = findState.clazz.getDeclaredMethods();
} catch (Throwable th) {
// Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
- methods = findState.clazz.getMethods();
+ try {
+ methods = findState.clazz.getMethods();
+ } catch (LinkageError error) { // super class of NoClassDefFoundError to be a bit more broad...
+ String msg = "Could not inspect methods of " + findState.clazz.getName();
+ if (ignoreGeneratedIndex) {
+ msg += ". Please consider using EventBus annotation processor to avoid reflection.";
+ } else {
+ msg += ". Please make this class visible to EventBus annotation processor to avoid reflection.";
+ }
+ throw new EventBusException(msg, error);
+ }
findState.skipSuperClasses = true;
}
for (Method method : methods) {
@@ -259,8 +269,10 @@ void moveToSuperclass() {
} else {
clazz = clazz.getSuperclass();
String clazzName = clazz.getName();
- /** Skip system classes, this just degrades performance. */
- if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") || clazzName.startsWith("android.")) {
+ // Skip system classes, this degrades performance.
+ // Also we might avoid some ClassNotFoundException (see FAQ for background).
+ if (clazzName.startsWith("java.") || clazzName.startsWith("javax.") ||
+ clazzName.startsWith("android.") || clazzName.startsWith("androidx.")) {
clazz = null;
}
}
diff --git a/EventBus/src/org/greenrobot/eventbus/ThreadMode.java b/EventBus/src/org/greenrobot/eventbus/ThreadMode.java
index 79d5dc43..b1ff2427 100644
--- a/EventBus/src/org/greenrobot/eventbus/ThreadMode.java
+++ b/EventBus/src/org/greenrobot/eventbus/ThreadMode.java
@@ -16,42 +16,53 @@
package org.greenrobot.eventbus;
/**
- * Each event handler method has a thread mode, which determines in which thread the method is to be called by EventBus.
- * EventBus takes care of threading independently from the posting thread.
- *
+ * Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus.
+ * EventBus takes care of threading independently of the posting thread.
+ *
* @see EventBus#register(Object)
- * @author Markus
*/
public enum ThreadMode {
/**
- * Subscriber will be called in the same thread, which is posting the event. This is the default. Event delivery
- * implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for
- * simple tasks that are known to complete is a very short time without requiring the main thread. Event handlers
+ * This is the default. Subscriber will be called directly in the same thread, which is posting the event. Event delivery
+ * implies the least overhead because it avoids thread switching completely. Thus, this is the recommended mode for
+ * simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers
* using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.
*/
POSTING,
/**
- * Subscriber will be called in Android's main thread (sometimes referred to as UI thread). If the posting thread is
- * the main thread, event handler methods will be called directly. Event handlers using this mode must return
- * quickly to avoid blocking the main thread.
+ * On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is
+ * the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event
+ * is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread.
+ *
+ * If not on Android, behaves the same as {@link #POSTING}.
*/
MAIN,
/**
- * Subscriber will be called in a background thread. If posting thread is not the main thread, event handler methods
+ * On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN},
+ * the event will always be queued for delivery. This ensures that the post call is non-blocking.
+ *
+ * If not on Android, behaves the same as {@link #POSTING}.
+ */
+ MAIN_ORDERED,
+
+ /**
+ * On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods
* will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single
- * background thread, that will deliver all its events sequentially. Event handlers using this mode should try to
+ * background thread, that will deliver all its events sequentially. Subscribers using this mode should try to
* return quickly to avoid blocking the background thread.
+ *
+ * If not on Android, always uses a background thread.
*/
BACKGROUND,
/**
- * Event handler methods are called in a separate thread. This is always independent from the posting thread and the
- * main thread. Posting events never wait for event handler methods using this mode. Event handler methods should
+ * Subscriber will be called in a separate thread. This is always independent of the posting thread and the
+ * main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should
* use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number
- * of long running asynchronous handler methods at the same time to limit the number of concurrent threads. EventBus
- * uses a thread pool to efficiently reuse threads from completed asynchronous event handler notifications.
+ * of long-running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus
+ * uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.
*/
ASYNC
}
\ No newline at end of file
diff --git a/EventBus/src/org/greenrobot/eventbus/android/AndroidComponents.java b/EventBus/src/org/greenrobot/eventbus/android/AndroidComponents.java
new file mode 100644
index 00000000..7138b6d9
--- /dev/null
+++ b/EventBus/src/org/greenrobot/eventbus/android/AndroidComponents.java
@@ -0,0 +1,31 @@
+package org.greenrobot.eventbus.android;
+
+import org.greenrobot.eventbus.Logger;
+import org.greenrobot.eventbus.MainThreadSupport;
+
+public abstract class AndroidComponents {
+
+ private static final AndroidComponents implementation;
+
+ static {
+ implementation = AndroidDependenciesDetector.isAndroidSDKAvailable()
+ ? AndroidDependenciesDetector.instantiateAndroidComponents()
+ : null;
+ }
+
+ public static boolean areAvailable() {
+ return implementation != null;
+ }
+
+ public static AndroidComponents get() {
+ return implementation;
+ }
+
+ public final Logger logger;
+ public final MainThreadSupport defaultMainThreadSupport;
+
+ public AndroidComponents(Logger logger, MainThreadSupport defaultMainThreadSupport) {
+ this.logger = logger;
+ this.defaultMainThreadSupport = defaultMainThreadSupport;
+ }
+}
diff --git a/EventBus/src/org/greenrobot/eventbus/android/AndroidDependenciesDetector.java b/EventBus/src/org/greenrobot/eventbus/android/AndroidDependenciesDetector.java
new file mode 100644
index 00000000..1783f143
--- /dev/null
+++ b/EventBus/src/org/greenrobot/eventbus/android/AndroidDependenciesDetector.java
@@ -0,0 +1,48 @@
+package org.greenrobot.eventbus.android;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+@SuppressWarnings("TryWithIdenticalCatches")
+public class AndroidDependenciesDetector {
+
+ public static boolean isAndroidSDKAvailable() {
+
+ try {
+ Class> looperClass = Class.forName("android.os.Looper");
+ Method getMainLooper = looperClass.getDeclaredMethod("getMainLooper");
+ Object mainLooper = getMainLooper.invoke(null);
+ return mainLooper != null;
+ }
+ catch (ClassNotFoundException ignored) {}
+ catch (NoSuchMethodException ignored) {}
+ catch (IllegalAccessException ignored) {}
+ catch (InvocationTargetException ignored) {}
+
+ return false;
+ }
+
+ private static final String ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME = "org.greenrobot.eventbus.android.AndroidComponentsImpl";
+
+ public static boolean areAndroidComponentsAvailable() {
+
+ try {
+ Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
+ return true;
+ }
+ catch (ClassNotFoundException ex) {
+ return false;
+ }
+ }
+
+ public static AndroidComponents instantiateAndroidComponents() {
+
+ try {
+ Class> impl = Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME);
+ return (AndroidComponents) impl.getConstructor().newInstance();
+ }
+ catch (Throwable ex) {
+ return null;
+ }
+ }
+}
diff --git a/EventBus/src/org/greenrobot/eventbus/meta/AbstractSubscriberInfo.java b/EventBus/src/org/greenrobot/eventbus/meta/AbstractSubscriberInfo.java
index b68de63a..9020c24b 100644
--- a/EventBus/src/org/greenrobot/eventbus/meta/AbstractSubscriberInfo.java
+++ b/EventBus/src/org/greenrobot/eventbus/meta/AbstractSubscriberInfo.java
@@ -46,7 +46,9 @@ public SubscriberInfo getSuperSubscriberInfo() {
}
try {
return superSubscriberInfoClass.newInstance();
- } catch (InstantiationException | IllegalAccessException e) {
+ } catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
diff --git a/EventBus/src/org/greenrobot/eventbus/util/AsyncExecutor.java b/EventBus/src/org/greenrobot/eventbus/util/AsyncExecutor.java
index c44c1366..bd9cb365 100644
--- a/EventBus/src/org/greenrobot/eventbus/util/AsyncExecutor.java
+++ b/EventBus/src/org/greenrobot/eventbus/util/AsyncExecutor.java
@@ -15,20 +15,26 @@
*/
package org.greenrobot.eventbus.util;
-import android.app.Activity;
-import android.util.Log;
-
import org.greenrobot.eventbus.EventBus;
import java.lang.reflect.Constructor;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
+import java.util.logging.Level;
/**
- * Executes an {@link RunnableEx} using a thread pool. Thrown exceptions are propagated by posting failure events of any
- * given type (default is {@link ThrowableFailureEvent}).
- *
- * @author Markus
+ * Executes an {@link RunnableEx} using a thread pool. Thrown exceptions are propagated by posting failure events.
+ * By default, uses {@link ThrowableFailureEvent}.
+ *
+ * Set a custom event type using {@link Builder#failureEventType(Class)}.
+ * The failure event class must have a constructor with one parameter of type {@link Throwable}.
+ * If using ProGuard or R8 make sure the constructor of the failure event class is kept, it is accessed via reflection.
+ * E.g. add a rule like
+ *
+ * -keepclassmembers class com.example.CustomThrowableFailureEvent {
+ * <init>(java.lang.Throwable);
+ * }
+ *
*/
public class AsyncExecutor {
@@ -59,10 +65,6 @@ public AsyncExecutor build() {
return buildForScope(null);
}
- public AsyncExecutor buildForActivityScope(Activity activity) {
- return buildForScope(activity.getClass());
- }
-
public AsyncExecutor buildForScope(Object executionContext) {
if (eventBus == null) {
eventBus = EventBus.getDefault();
@@ -109,24 +111,21 @@ private AsyncExecutor(Executor threadPool, EventBus eventBus, Class> failureEv
/** Posts an failure event if the given {@link RunnableEx} throws an Exception. */
public void execute(final RunnableEx runnable) {
- threadPool.execute(new Runnable() {
- @Override
- public void run() {
+ threadPool.execute(() -> {
+ try {
+ runnable.run();
+ } catch (Exception e) {
+ Object event;
try {
- runnable.run();
- } catch (Exception e) {
- Object event;
- try {
- event = failureEventConstructor.newInstance(e);
- } catch (Exception e1) {
- Log.e(EventBus.TAG, "Original exception:", e);
- throw new RuntimeException("Could not create failure event", e1);
- }
- if (event instanceof HasExecutionScope) {
- ((HasExecutionScope) event).setExecutionScope(scope);
- }
- eventBus.post(event);
+ event = failureEventConstructor.newInstance(e);
+ } catch (Exception e1) {
+ eventBus.getLogger().log(Level.SEVERE, "Original exception:", e);
+ throw new RuntimeException("Could not create failure event", e1);
+ }
+ if (event instanceof HasExecutionScope) {
+ ((HasExecutionScope) event).setExecutionScope(scope);
}
+ eventBus.post(event);
}
});
}
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogConfig.java b/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogConfig.java
deleted file mode 100644
index 95e84c72..00000000
--- a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogConfig.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.greenrobot.eventbus.util;
-
-import android.content.res.Resources;
-import android.util.Log;
-
-import org.greenrobot.eventbus.EventBus;
-
-public class ErrorDialogConfig {
- final Resources resources;
- final int defaultTitleId;
- final int defaultErrorMsgId;
- final ExceptionToResourceMapping mapping;
-
- EventBus eventBus;
- boolean logExceptions = true;
- String tagForLoggingExceptions;
- int defaultDialogIconId;
- Class> defaultEventTypeOnDialogClosed;
-
- public ErrorDialogConfig(Resources resources, int defaultTitleId, int defaultMsgId) {
- this.resources = resources;
- this.defaultTitleId = defaultTitleId;
- this.defaultErrorMsgId = defaultMsgId;
- mapping = new ExceptionToResourceMapping();
- }
-
- public ErrorDialogConfig addMapping(Class extends Throwable> clazz, int msgId) {
- mapping.addMapping(clazz, msgId);
- return this;
- }
-
- public int getMessageIdForThrowable(final Throwable throwable) {
- Integer resId = mapping.mapThrowable(throwable);
- if (resId != null) {
- return resId;
- } else {
- Log.d(EventBus.TAG, "No specific message ressource ID found for " + throwable);
- return defaultErrorMsgId;
- }
- }
-
- public void setDefaultDialogIconId(int defaultDialogIconId) {
- this.defaultDialogIconId = defaultDialogIconId;
- }
-
- public void setDefaultEventTypeOnDialogClosed(Class> defaultEventTypeOnDialogClosed) {
- this.defaultEventTypeOnDialogClosed = defaultEventTypeOnDialogClosed;
- }
-
- public void disableExceptionLogging() {
- logExceptions = false;
- }
-
- public void setTagForLoggingExceptions(String tagForLoggingExceptions) {
- this.tagForLoggingExceptions = tagForLoggingExceptions;
- }
-
- public void setEventBus(EventBus eventBus) {
- this.eventBus = eventBus;
- }
-
- /** eventBus!=null ? eventBus: EventBus.getDefault() */
- EventBus getEventBus() {
- return eventBus!=null ? eventBus: EventBus.getDefault();
- }
-}
\ No newline at end of file
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragmentFactory.java b/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragmentFactory.java
deleted file mode 100644
index 27ab963d..00000000
--- a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragmentFactory.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.greenrobot.eventbus.util;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-
-/**
- * Factory to allow injecting a more complex exception mapping; typically you would subclass one of {@link Honeycomb} or
- * {@link Support}.
- */
-public abstract class ErrorDialogFragmentFactory {
- protected final ErrorDialogConfig config;
-
- protected ErrorDialogFragmentFactory(ErrorDialogConfig config) {
- this.config = config;
- }
-
- /**
- * Prepares the fragment's arguments and creates the fragment. May be overridden to provide custom error fragments.
- */
- protected T prepareErrorFragment(ThrowableFailureEvent event, boolean finishAfterDialog,
- Bundle argumentsForErrorDialog) {
- if (event.isSuppressErrorUi()) {
- // Show nothing by default
- return null;
- }
- Bundle bundle;
- if (argumentsForErrorDialog != null) {
- bundle = (Bundle) argumentsForErrorDialog.clone();
- } else {
- bundle = new Bundle();
- }
-
- if (!bundle.containsKey(ErrorDialogManager.KEY_TITLE)) {
- String title = getTitleFor(event, bundle);
- bundle.putString(ErrorDialogManager.KEY_TITLE, title);
- }
- if (!bundle.containsKey(ErrorDialogManager.KEY_MESSAGE)) {
- String message = getMessageFor(event, bundle);
- bundle.putString(ErrorDialogManager.KEY_MESSAGE, message);
- }
- if (!bundle.containsKey(ErrorDialogManager.KEY_FINISH_AFTER_DIALOG)) {
- bundle.putBoolean(ErrorDialogManager.KEY_FINISH_AFTER_DIALOG, finishAfterDialog);
- }
- if (!bundle.containsKey(ErrorDialogManager.KEY_EVENT_TYPE_ON_CLOSE)
- && config.defaultEventTypeOnDialogClosed != null) {
- bundle.putSerializable(ErrorDialogManager.KEY_EVENT_TYPE_ON_CLOSE, config.defaultEventTypeOnDialogClosed);
- }
- if (!bundle.containsKey(ErrorDialogManager.KEY_ICON_ID) && config.defaultDialogIconId != 0) {
- bundle.putInt(ErrorDialogManager.KEY_ICON_ID, config.defaultDialogIconId);
- }
- return createErrorFragment(event, bundle);
- }
-
- /** Returns either a new Honeycomb+ or a new support library DialogFragment. */
- protected abstract T createErrorFragment(ThrowableFailureEvent event, Bundle arguments);
-
- /** May be overridden to provide custom error title. */
- protected String getTitleFor(ThrowableFailureEvent event, Bundle arguments) {
- return config.resources.getString(config.defaultTitleId);
- }
-
- /** May be overridden to provide custom error messages. */
- protected String getMessageFor(ThrowableFailureEvent event, Bundle arguments) {
- int msgResId = config.getMessageIdForThrowable(event.throwable);
- return config.resources.getString(msgResId);
- }
-
- public static class Support extends ErrorDialogFragmentFactory {
-
- public Support(ErrorDialogConfig config) {
- super(config);
- }
-
- protected Fragment createErrorFragment(ThrowableFailureEvent event, Bundle arguments) {
- ErrorDialogFragments.Support errorFragment = new ErrorDialogFragments.Support();
- errorFragment.setArguments(arguments);
- return errorFragment;
- }
-
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public static class Honeycomb extends ErrorDialogFragmentFactory {
-
- public Honeycomb(ErrorDialogConfig config) {
- super(config);
- }
-
- protected android.app.Fragment createErrorFragment(ThrowableFailureEvent event, Bundle arguments) {
- ErrorDialogFragments.Honeycomb errorFragment = new ErrorDialogFragments.Honeycomb();
- errorFragment.setArguments(arguments);
- return errorFragment;
- }
-
- }
-}
\ No newline at end of file
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragments.java b/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragments.java
deleted file mode 100644
index 49174766..00000000
--- a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogFragments.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.greenrobot.eventbus.util;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-
-import org.greenrobot.eventbus.EventBus;
-
-public class ErrorDialogFragments {
- /** TODO Use config: Icon res ID to use for all error dialogs. May be configured by each app (optional). */
- public static int ERROR_DIALOG_ICON = 0;
-
- /** TODO Use config: Event class to be fired on dismissing the dialog by the user. May be configured by each app. */
- public static Class> EVENT_TYPE_ON_CLICK;
-
- public static Dialog createDialog(Context context, Bundle arguments, OnClickListener onClickListener) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(arguments.getString(ErrorDialogManager.KEY_TITLE));
- builder.setMessage(arguments.getString(ErrorDialogManager.KEY_MESSAGE));
- if (ERROR_DIALOG_ICON != 0) {
- builder.setIcon(ERROR_DIALOG_ICON);
- }
- builder.setPositiveButton(android.R.string.ok, onClickListener);
- return builder.create();
- }
-
- public static void handleOnClick(DialogInterface dialog, int which, Activity activity, Bundle arguments) {
- if (EVENT_TYPE_ON_CLICK != null) {
- Object event;
- try {
- event = EVENT_TYPE_ON_CLICK.newInstance();
- } catch (Exception e) {
- throw new RuntimeException("Event cannot be constructed", e);
- }
- EventBus eventBus = ErrorDialogManager.factory.config.getEventBus();
- eventBus.post(event);
- }
- boolean finish = arguments.getBoolean(ErrorDialogManager.KEY_FINISH_AFTER_DIALOG, false);
- if (finish && activity != null) {
- activity.finish();
- }
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public static class Honeycomb extends android.app.DialogFragment implements OnClickListener {
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return createDialog(getActivity(), getArguments(), this);
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- handleOnClick(dialog, which, getActivity(), getArguments());
- }
- }
-
- public static class Support extends DialogFragment implements OnClickListener {
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- return createDialog(getActivity(), getArguments(), this);
- }
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- handleOnClick(dialog, which, getActivity(), getArguments());
- }
- }
-}
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogManager.java b/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogManager.java
deleted file mode 100644
index 9d5ccf2c..00000000
--- a/EventBus/src/org/greenrobot/eventbus/util/ErrorDialogManager.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.greenrobot.eventbus.util;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.app.Application;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.DialogFragment;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.FragmentManager;
-import android.util.Log;
-
-import org.greenrobot.eventbus.EventBus;
-
-/**
- * Central class for app that want to use event based error dialogs.
- *
- * How to use:
- *
- * - Set the {@link #factory} to configure dialogs for your app, typically in {@link Application#onCreate()}
- * - Use one of {@link #attachTo(Activity)}, {@link #attachTo(Activity, boolean)} or
- * {@link #attachTo(Activity, boolean, Bundle)} in your Activity, typically in onCreate.
- *
- *
- * For more complex mappings, you can supply your own {@link ErrorDialogFragmentFactory}.
- *
- * @author Markus
- */
-public class ErrorDialogManager {
-
- public static class SupportManagerFragment extends Fragment {
- protected boolean finishAfterDialog;
- protected Bundle argumentsForErrorDialog;
- private EventBus eventBus;
- private boolean skipRegisterOnNextResume;
- private Object executionScope;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- eventBus = ErrorDialogManager.factory.config.getEventBus();
- eventBus.register(this);
- skipRegisterOnNextResume = true;
- }
-
- @Override
- public void onResume() {
- super.onResume();
- if (skipRegisterOnNextResume) {
- // registered in onCreate, skip registration in this run
- skipRegisterOnNextResume = false;
- } else {
- eventBus = ErrorDialogManager.factory.config.getEventBus();
- eventBus.register(this);
- }
- }
-
- @Override
- public void onPause() {
- eventBus.unregister(this);
- super.onPause();
- }
-
- public void onEventMainThread(ThrowableFailureEvent event) {
- if (!isInExecutionScope(executionScope, event)) {
- return;
- }
- checkLogException(event);
- // Execute pending commits before finding to avoid multiple error fragments being shown
- FragmentManager fm = getFragmentManager();
- fm.executePendingTransactions();
-
- DialogFragment existingFragment = (DialogFragment) fm.findFragmentByTag(TAG_ERROR_DIALOG);
- if (existingFragment != null) {
- // Just show the latest error
- existingFragment.dismiss();
- }
-
- android.support.v4.app.DialogFragment errorFragment = (android.support.v4.app.DialogFragment) factory
- .prepareErrorFragment(event, finishAfterDialog, argumentsForErrorDialog);
- if (errorFragment != null) {
- errorFragment.show(fm, TAG_ERROR_DIALOG);
- }
- }
-
- public static void attachTo(Activity activity, Object executionScope, boolean finishAfterDialog,
- Bundle argumentsForErrorDialog) {
- FragmentManager fm = ((FragmentActivity) activity).getSupportFragmentManager();
- SupportManagerFragment fragment = (SupportManagerFragment) fm.findFragmentByTag(TAG_ERROR_DIALOG_MANAGER);
- if (fragment == null) {
- fragment = new SupportManagerFragment();
- fm.beginTransaction().add(fragment, TAG_ERROR_DIALOG_MANAGER).commit();
- fm.executePendingTransactions();
- }
- fragment.finishAfterDialog = finishAfterDialog;
- fragment.argumentsForErrorDialog = argumentsForErrorDialog;
- fragment.executionScope = executionScope;
- }
- }
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- public static class HoneycombManagerFragment extends android.app.Fragment {
- protected boolean finishAfterDialog;
- protected Bundle argumentsForErrorDialog;
- private EventBus eventBus;
- private Object executionScope;
-
- @Override
- public void onResume() {
- super.onResume();
- eventBus = ErrorDialogManager.factory.config.getEventBus();
- eventBus.register(this);
- }
-
- @Override
- public void onPause() {
- eventBus.unregister(this);
- super.onPause();
- }
-
- public void onEventMainThread(ThrowableFailureEvent event) {
- if (!isInExecutionScope(executionScope, event)) {
- return;
- }
- checkLogException(event);
-
- // Execute pending commits before finding to avoid multiple error fragments being shown
- android.app.FragmentManager fm = getFragmentManager();
- fm.executePendingTransactions();
-
- android.app.DialogFragment existingFragment = (android.app.DialogFragment) fm
- .findFragmentByTag(TAG_ERROR_DIALOG);
- if (existingFragment != null) {
- // Just show the latest error
- existingFragment.dismiss();
- }
-
- android.app.DialogFragment errorFragment = (android.app.DialogFragment) factory.prepareErrorFragment(event,
- finishAfterDialog, argumentsForErrorDialog);
- if (errorFragment != null) {
- errorFragment.show(fm, TAG_ERROR_DIALOG);
- }
- }
-
- public static void attachTo(Activity activity, Object executionScope, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
- android.app.FragmentManager fm = activity.getFragmentManager();
- HoneycombManagerFragment fragment = (HoneycombManagerFragment) fm
- .findFragmentByTag(TAG_ERROR_DIALOG_MANAGER);
- if (fragment == null) {
- fragment = new HoneycombManagerFragment();
- fm.beginTransaction().add(fragment, TAG_ERROR_DIALOG_MANAGER).commit();
- fm.executePendingTransactions();
- }
- fragment.finishAfterDialog = finishAfterDialog;
- fragment.argumentsForErrorDialog = argumentsForErrorDialog;
- fragment.executionScope = executionScope;
- }
- }
-
- /** Must be set by the application. */
- public static ErrorDialogFragmentFactory> factory;
-
- protected static final String TAG_ERROR_DIALOG = "de.greenrobot.eventbus.error_dialog";
- protected static final String TAG_ERROR_DIALOG_MANAGER = "de.greenrobot.eventbus.error_dialog_manager";
-
- public static final String KEY_TITLE = "de.greenrobot.eventbus.errordialog.title";
- public static final String KEY_MESSAGE = "de.greenrobot.eventbus.errordialog.message";
- public static final String KEY_FINISH_AFTER_DIALOG = "de.greenrobot.eventbus.errordialog.finish_after_dialog";
- public static final String KEY_ICON_ID = "de.greenrobot.eventbus.errordialog.icon_id";
- public static final String KEY_EVENT_TYPE_ON_CLOSE = "de.greenrobot.eventbus.errordialog.event_type_on_close";
-
- /** Scope is limited to the activity's class. */
- public static void attachTo(Activity activity) {
- attachTo(activity, false, null);
- }
-
- /** Scope is limited to the activity's class. */
- public static void attachTo(Activity activity, boolean finishAfterDialog) {
- attachTo(activity, finishAfterDialog, null);
- }
-
- /** Scope is limited to the activity's class. */
- public static void attachTo(Activity activity, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
- Object executionScope = activity.getClass();
- attachTo(activity, executionScope, finishAfterDialog, argumentsForErrorDialog);
- }
-
- public static void attachTo(Activity activity, Object executionScope, boolean finishAfterDialog, Bundle argumentsForErrorDialog) {
- if (factory == null) {
- throw new RuntimeException("You must set the static factory field to configure error dialogs for your app.");
- }
- if (isSupportActivity(activity)) {
- SupportManagerFragment.attachTo(activity, executionScope, finishAfterDialog, argumentsForErrorDialog);
- } else {
- HoneycombManagerFragment.attachTo(activity, executionScope, finishAfterDialog, argumentsForErrorDialog);
- }
- }
-
- private static boolean isSupportActivity(Activity activity) {
- boolean isSupport = false;
- for (Class> c = activity.getClass().getSuperclass();; c = c.getSuperclass()) {
- if (c == null) {
- throw new RuntimeException("Illegal activity type: " + activity.getClass());
- }
- String name = c.getName();
- if (name.equals("android.support.v4.app.FragmentActivity")) {
- isSupport = true;
- break;
- } else if (name.startsWith("com.actionbarsherlock.app")
- && (name.endsWith(".SherlockActivity") || name.endsWith(".SherlockListActivity") || name
- .endsWith(".SherlockPreferenceActivity"))) {
- throw new RuntimeException("Please use SherlockFragmentActivity. Illegal activity: " + name);
- } else if (name.equals("android.app.Activity")) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
- throw new RuntimeException(
- "Illegal activity without fragment support. Either use Android 3.0+ or android.support.v4.app.FragmentActivity.");
- }
- break;
- }
- }
- return isSupport;
- }
-
- protected static void checkLogException(ThrowableFailureEvent event) {
- if (factory.config.logExceptions) {
- String tag = factory.config.tagForLoggingExceptions;
- if (tag == null) {
- tag = EventBus.TAG;
- }
- Log.i(tag, "Error dialog manager received exception", event.throwable);
- }
- }
-
- private static boolean isInExecutionScope(Object executionScope, ThrowableFailureEvent event) {
- if (event != null) {
- Object eventExecutionScope = event.getExecutionScope();
- if (eventExecutionScope != null && !eventExecutionScope.equals(executionScope)) {
- // Event not in our scope, do nothing
- return false;
- }
- }
- return true;
- }
-
-}
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ExceptionToResourceMapping.java b/EventBus/src/org/greenrobot/eventbus/util/ExceptionToResourceMapping.java
index 9ab0d006..083bd394 100644
--- a/EventBus/src/org/greenrobot/eventbus/util/ExceptionToResourceMapping.java
+++ b/EventBus/src/org/greenrobot/eventbus/util/ExceptionToResourceMapping.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ * Copyright (C) 2012-2020 Markus Junginger, greenrobot (http://greenrobot.org)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +16,13 @@
package org.greenrobot.eventbus.util;
-import android.util.Log;
-
-import org.greenrobot.eventbus.EventBus;
+import org.greenrobot.eventbus.Logger;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.logging.Level;
/**
@@ -36,7 +35,7 @@ public class ExceptionToResourceMapping {
public final Map, Integer> throwableToMsgIdMap;
public ExceptionToResourceMapping() {
- throwableToMsgIdMap = new HashMap, Integer>();
+ throwableToMsgIdMap = new HashMap<>();
}
/** Looks at the exception and its causes trying to find an ID. */
@@ -52,7 +51,8 @@ public Integer mapThrowable(final Throwable throwable) {
throwableToCheck = throwableToCheck.getCause();
depthToGo--;
if (depthToGo <= 0 || throwableToCheck == throwable || throwableToCheck == null) {
- Log.d(EventBus.TAG, "No specific message ressource ID found for " + throwable);
+ Logger logger = Logger.Default.get(); // No EventBus instance here
+ logger.log(Level.FINE, "No specific message resource ID found for " + throwable);
// return config.defaultErrorMsgId;
return null;
}
diff --git a/EventBus/src/org/greenrobot/eventbus/util/ThrowableFailureEvent.java b/EventBus/src/org/greenrobot/eventbus/util/ThrowableFailureEvent.java
index 9b7b80b6..7707e289 100644
--- a/EventBus/src/org/greenrobot/eventbus/util/ThrowableFailureEvent.java
+++ b/EventBus/src/org/greenrobot/eventbus/util/ThrowableFailureEvent.java
@@ -16,8 +16,8 @@
package org.greenrobot.eventbus.util;
/**
- * A generic failure event, which can be used by apps to propagate thrown exceptions. Also used in conjunction with
- * {@link ErrorDialogManager}.
+ * A generic failure event, which can be used by apps to propagate thrown exceptions.
+ * Used as default failure event by {@link AsyncExecutor}.
*/
public class ThrowableFailureEvent implements HasExecutionScope {
protected final Throwable throwable;
diff --git a/EventBusAnnotationProcessor/build.gradle b/EventBusAnnotationProcessor/build.gradle
index 4dfa5eca..0ec77d93 100644
--- a/EventBusAnnotationProcessor/build.gradle
+++ b/EventBusAnnotationProcessor/build.gradle
@@ -1,41 +1,23 @@
apply plugin: 'java'
-apply plugin: 'maven'
-apply plugin: 'signing'
-archivesBaseName = 'eventbus-annotation-processor'
-group = 'org.greenrobot'
-version = '3.0.1'
+group = rootProject.group
+version = rootProject.version
-sourceCompatibility = 1.7
-
-def isSnapshot = version.endsWith('-SNAPSHOT')
-def sonatypeRepositoryUrl
-if (isSnapshot) {
- sonatypeRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
-} else {
- sonatypeRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
-}
-
-repositories {
- mavenCentral()
-}
-
-// Still unsupported, see http://issues.gradle.org/browse/GRADLE-784
-// Like this, it won't appear at all in the POM
-configurations {
- provided
- deployerJars
-}
+java.sourceCompatibility = JavaVersion.VERSION_1_8
+java.targetCompatibility = JavaVersion.VERSION_1_8
dependencies {
- compile project(':EventBus')
- compile 'de.greenrobot:java-common:2.3.1'
- deployerJars 'org.apache.maven.wagon:wagon-webdav:1.0-beta-2'
+ implementation project(':eventbus-java')
+ implementation 'de.greenrobot:java-common:2.3.1'
+
+ // Generates the required META-INF descriptor to make the processor incremental.
+ def incap = '0.2'
+ compileOnly "net.ltgt.gradle.incap:incap:$incap"
+ annotationProcessor "net.ltgt.gradle.incap:incap-processor:$incap"
}
sourceSets {
main {
- compileClasspath += configurations.provided
java {
srcDir 'src'
}
@@ -46,91 +28,35 @@ sourceSets {
}
javadoc {
- classpath += configurations.provided
title = "EventBus Annotation Processor ${version} API"
- options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2015-2016 greenrobot.org. All Rights Reserved.'
+ options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2015-2020 greenrobot.org. All Rights Reserved.'
}
task javadocJar(type: Jar, dependsOn: javadoc) {
- classifier = 'javadoc'
+ archiveClassifier.set("javadoc")
from 'build/docs/javadoc'
}
task sourcesJar(type: Jar) {
+ archiveClassifier.set("sources")
from sourceSets.main.allSource
- classifier = 'sources'
-}
-
-artifacts {
- archives jar
- archives javadocJar
- archives sourcesJar
-}
-
-signing {
- if (project.hasProperty('signing.keyId') && project.hasProperty('signing.password') &&
- project.hasProperty('signing.secretKeyRingFile')) {
- sign configurations.archives
- } else {
- println "Signing information missing/incomplete for ${project.name}"
- }
}
-uploadArchives {
- repositories {
- mavenDeployer {
- if (project.hasProperty('preferedRepo') && project.hasProperty('preferedUsername')
- && project.hasProperty('preferedPassword')) {
- configuration = configurations.deployerJars
- repository(url: preferedRepo) {
- authentication(userName: preferedUsername, password: preferedPassword)
- }
- } else if (project.hasProperty('sonatypeUsername') && project.hasProperty('sonatypePassword')) {
- beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
- repository(url: sonatypeRepositoryUrl) {
- authentication(userName: sonatypeUsername, password: sonatypePassword)
- }
- } else {
- println "Settings sonatypeUsername/sonatypePassword missing/incomplete for ${project.name}"
- }
-
- pom.project {
- name 'EventBus Annotation Processor'
- packaging 'jar'
- description 'Precompiler for EventBus Annotations.'
- url 'http://greenrobot.org/eventbus/'
-
- scm {
- url 'https://github.com/greenrobot/EventBus'
- connection 'scm:git@github.com:greenrobot/EventBus.git'
- developerConnection 'scm:git@github.com:greenrobot/EventBus.git'
- }
-
- licenses {
- license {
- name 'The Apache Software License, Version 2.0'
- url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
- distribution 'repo'
- }
- }
-
- developers {
- developer {
- id 'greenrobot'
- name 'greenrobot'
- }
- }
-
- issueManagement {
- system 'GitHub Issues'
- url 'https://github.com/greenrobot/EventBus/issues'
- }
-
- organization {
- name 'greenrobot'
- url 'http://greenrobot.org'
- }
+apply from: rootProject.file("gradle/publish.gradle")
+// Set project-specific properties
+afterEvaluate {
+ publishing.publications {
+ mavenJava(MavenPublication) {
+ artifactId = "eventbus-annotation-processor"
+
+ from components.java
+ artifact javadocJar
+ artifact sourcesJar
+ pom {
+ name = "EventBus Annotation Processor"
+ description = "Precompiler for EventBus Annotations."
+ packaging = "jar"
}
}
}
-}
\ No newline at end of file
+}
diff --git a/EventBusAnnotationProcessor/settings.gradle b/EventBusAnnotationProcessor/settings.gradle
deleted file mode 100644
index 51ebbb79..00000000
--- a/EventBusAnnotationProcessor/settings.gradle
+++ /dev/null
@@ -1 +0,0 @@
-rootProject.name = 'eventbus-annotation-processor'
\ No newline at end of file
diff --git a/EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java b/EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java
index c37c18a5..058bc36e 100644
--- a/EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java
+++ b/EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java
@@ -15,6 +15,8 @@
*/
package org.greenrobot.eventbus.annotationprocessor;
+import net.ltgt.gradle.incap.IncrementalAnnotationProcessor;
+
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
@@ -46,8 +48,16 @@
import de.greenrobot.common.ListMap;
+
+import static net.ltgt.gradle.incap.IncrementalAnnotationProcessorType.AGGREGATING;
+
+/**
+ * Is an aggregating processor as it writes a single file, the subscriber index file,
+ * based on found elements with the @Subscriber annotation.
+ */
@SupportedAnnotationTypes("org.greenrobot.eventbus.Subscribe")
@SupportedOptions(value = {"eventBusIndex", "verbose"})
+@IncrementalAnnotationProcessor(AGGREGATING)
public class EventBusAnnotationProcessor extends AbstractProcessor {
public static final String OPTION_EVENT_BUS_INDEX = "eventBusIndex";
public static final String OPTION_VERBOSE = "verbose";
diff --git a/EventBusPerformance/AndroidManifest.xml b/EventBusPerformance/AndroidManifest.xml
index af353b5d..530cafeb 100644
--- a/EventBusPerformance/AndroidManifest.xml
+++ b/EventBusPerformance/AndroidManifest.xml
@@ -1,12 +1,6 @@
-
-
+ package="org.greenrobot.eventbusperf">
- POSTING
- MAIN
+ - MAIN_ORDERED
- BACKGROUND
- ASYNC
diff --git a/EventBusPerformance/src/org/greenrobot/eventbusperf/TestRunnerActivity.java b/EventBusPerformance/src/org/greenrobot/eventbusperf/TestRunnerActivity.java
index e22631c1..b21efabf 100644
--- a/EventBusPerformance/src/org/greenrobot/eventbusperf/TestRunnerActivity.java
+++ b/EventBusPerformance/src/org/greenrobot/eventbusperf/TestRunnerActivity.java
@@ -42,7 +42,7 @@ public class TestRunnerActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_runtests);
- textViewResult = (TextView) findViewById(R.id.textViewResult);
+ textViewResult = findViewById(R.id.textViewResult);
controlBus = new EventBus();
controlBus.register(this);
}
diff --git a/EventBusPerformance/src/org/greenrobot/eventbusperf/TestSetupActivity.java b/EventBusPerformance/src/org/greenrobot/eventbusperf/TestSetupActivity.java
index 3488b8da..626f8a0b 100644
--- a/EventBusPerformance/src/org/greenrobot/eventbusperf/TestSetupActivity.java
+++ b/EventBusPerformance/src/org/greenrobot/eventbusperf/TestSetupActivity.java
@@ -50,7 +50,7 @@ public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setuptests);
- Spinner spinnerRun = (Spinner) findViewById(R.id.spinnerTestToRun);
+ Spinner spinnerRun = findViewById(R.id.spinnerTestToRun);
spinnerRun.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView> adapter, View v, int pos, long lng) {
@@ -65,15 +65,15 @@ public void onNothingSelected(AdapterView> arg0) {
}
public void checkEventBus(View v) {
- Spinner spinnerThread = (Spinner) findViewById(R.id.spinnerThread);
- CheckBox checkBoxEventBus = (CheckBox) findViewById(R.id.checkBoxEventBus);
+ Spinner spinnerThread = findViewById(R.id.spinnerThread);
+ CheckBox checkBoxEventBus = findViewById(R.id.checkBoxEventBus);
int visibility = checkBoxEventBus.isChecked() ? View.VISIBLE : View.GONE;
spinnerThread.setVisibility(visibility);
}
public void startClick(View v) {
TestParams params = new TestParams();
- Spinner spinnerThread = (Spinner) findViewById(R.id.spinnerThread);
+ Spinner spinnerThread = findViewById(R.id.spinnerThread);
String threadModeStr = spinnerThread.getSelectedItem().toString();
ThreadMode threadMode = ThreadMode.valueOf(threadModeStr);
params.setThreadMode(threadMode);
@@ -81,13 +81,13 @@ public void startClick(View v) {
params.setEventInheritance(((CheckBox) findViewById(R.id.checkBoxEventBusEventHierarchy)).isChecked());
params.setIgnoreGeneratedIndex(((CheckBox) findViewById(R.id.checkBoxEventBusIgnoreGeneratedIndex)).isChecked());
- EditText editTextEvent = (EditText) findViewById(R.id.editTextEvent);
+ EditText editTextEvent = findViewById(R.id.editTextEvent);
params.setEventCount(Integer.parseInt(editTextEvent.getText().toString()));
- EditText editTextSubscriber = (EditText) findViewById(R.id.editTextSubscribe);
+ EditText editTextSubscriber = findViewById(R.id.editTextSubscribe);
params.setSubscriberCount(Integer.parseInt(editTextSubscriber.getText().toString()));
- Spinner spinnerTestToRun = (Spinner) findViewById(R.id.spinnerTestToRun);
+ Spinner spinnerTestToRun = findViewById(R.id.spinnerTestToRun);
int testPos = spinnerTestToRun.getSelectedItemPosition();
params.setTestNumber(testPos + 1);
ArrayList> testClasses = initTestClasses(testPos);
@@ -103,10 +103,10 @@ public void startClick(View v) {
private ArrayList> initTestClasses(int testPos) {
ArrayList> testClasses = new ArrayList>();
// the attributes are putted in the intent (eventbus, otto, broadcast, local broadcast)
- final CheckBox checkBoxEventBus = (CheckBox) findViewById(R.id.checkBoxEventBus);
- final CheckBox checkBoxOtto = (CheckBox) findViewById(R.id.checkBoxOtto);
- final CheckBox checkBoxBroadcast = (CheckBox) findViewById(R.id.checkBoxBroadcast);
- final CheckBox checkBoxLocalBroadcast = (CheckBox) findViewById(R.id.checkBoxLocalBroadcast);
+ final CheckBox checkBoxEventBus = findViewById(R.id.checkBoxEventBus);
+ final CheckBox checkBoxOtto = findViewById(R.id.checkBoxOtto);
+ final CheckBox checkBoxBroadcast = findViewById(R.id.checkBoxBroadcast);
+ final CheckBox checkBoxLocalBroadcast = findViewById(R.id.checkBoxLocalBroadcast);
if (checkBoxEventBus.isChecked()) {
testClasses.add(TEST_CLASSES_EVENTBUS[testPos]);
}
diff --git a/EventBusPerformance/src/org/greenrobot/eventbusperf/testsubject/PerfTestEventBus.java b/EventBusPerformance/src/org/greenrobot/eventbusperf/testsubject/PerfTestEventBus.java
index 7ceb8e6d..f0a5e2f8 100644
--- a/EventBusPerformance/src/org/greenrobot/eventbusperf/testsubject/PerfTestEventBus.java
+++ b/EventBusPerformance/src/org/greenrobot/eventbusperf/testsubject/PerfTestEventBus.java
@@ -66,6 +66,8 @@ private Class> getSubscriberClassForThreadMode() {
switch (params.getThreadMode()) {
case MAIN:
return SubscribeClassEventBusMain.class;
+ case MAIN_ORDERED:
+ return SubscribeClassEventBusMainOrdered.class;
case BACKGROUND:
return SubscribeClassEventBusBackground.class;
case ASYNC:
@@ -227,6 +229,28 @@ public void dummy5() {
}
}
+ public class SubscribeClassEventBusMainOrdered {
+ @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
+ public void onEvent(TestEvent event) {
+ eventsReceivedCount.incrementAndGet();
+ }
+
+ public void dummy() {
+ }
+
+ public void dummy2() {
+ }
+
+ public void dummy3() {
+ }
+
+ public void dummy4() {
+ }
+
+ public void dummy5() {
+ }
+ }
+
public class SubscribeClassEventBusBackground {
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onEventBackgroundThread(TestEvent event) {
diff --git a/EventBusTest/AndroidManifest.xml b/EventBusTest/AndroidManifest.xml
index 22aedee0..657ad878 100644
--- a/EventBusTest/AndroidManifest.xml
+++ b/EventBusTest/AndroidManifest.xml
@@ -1,20 +1,14 @@
+ xmlns:tools="http://schemas.android.com/tools"
+ package="org.greenrobot.eventbus">
-
-
-
-
+ android:label="EventBus Test"
+ tools:ignore="GoogleAppIndexingWarning,MissingApplicationIcon">
\ No newline at end of file
diff --git a/EventBusTest/build.gradle b/EventBusTest/build.gradle
index a1d04468..2ca34312 100644
--- a/EventBusTest/build.gradle
+++ b/EventBusTest/build.gradle
@@ -1,34 +1,30 @@
buildscript {
repositories {
- jcenter()
+ google()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.2.1'
- classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
+ // Note: IntelliJ IDEA 2021.1 only supports up to version 4.1
+ classpath 'com.android.tools.build:gradle:4.1.3'
}
}
apply plugin: 'com.android.application'
-apply plugin: 'com.neenbedankt.android-apt'
-
-sourceCompatibility = 1.7
-
-repositories {
- jcenter()
-}
dependencies {
- androidTestApt project(':EventBusAnnotationProcessor')
- androidTestCompile project(':EventBus')
- compile fileTree(dir: 'libs', include: '*.jar')
- androidTestCompile 'com.android.support.test:runner:0.4.1'
- androidTestCompile 'com.android.support.test:rules:0.4.1'
+ androidTestImplementation project(':eventbus-android')
+ androidTestImplementation project(':EventBusTestJava')
+ androidTestAnnotationProcessor project(':eventbus-annotation-processor')
+ // Trying to repro bug:
+// androidTestAnnotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.0'
+ implementation fileTree(dir: 'libs', include: '*.jar')
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation 'com.android.support.test:rules:1.0.2'
}
android {
- buildToolsVersion '23.0.2' // When updating, don't forget to adjust .travis.yml
- compileSdkVersion 19
+ compileSdkVersion _compileSdkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_7
@@ -46,14 +42,28 @@ android {
}
defaultConfig {
+ minSdkVersion 9
+ targetSdkVersion 26
+ versionCode 1
+ versionName "1.0"
+
testApplicationId "de.greenrobot.event.test"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
+ javaCompileOptions {
+ annotationProcessorOptions {
+ arguments = [ eventBusIndex : 'org.greenrobot.eventbus.EventBusTestsIndex' ]
+ }
+ }
}
-}
-apt {
- arguments {
- eventBusIndex "org.greenrobot.eventbus.EventBusTestsIndex"
+ useLibrary 'android.test.base'
+
+ lintOptions {
+ // To see problems right away, also nice for Travis CI
+ textOutput 'stdout'
+
+ // TODO FIXME: Travis only error
+ abortOnError false
}
}
-
diff --git a/EventBusTest/src/org/greenrobot/eventbus/AbstractAndroidEventBusTest.java b/EventBusTest/src/org/greenrobot/eventbus/AbstractAndroidEventBusTest.java
new file mode 100644
index 00000000..13178206
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/AbstractAndroidEventBusTest.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+import android.annotation.SuppressLint;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+
+
+import static org.junit.Assert.assertFalse;
+
+/**
+ * @author Markus Junginger, greenrobot
+ */
+@RunWith(AndroidJUnit4.class)
+public abstract class AbstractAndroidEventBusTest extends AbstractEventBusTest {
+ private EventPostHandler mainPoster;
+
+ public AbstractAndroidEventBusTest() {
+ this(false);
+ }
+
+ public AbstractAndroidEventBusTest(boolean collectEventsReceived) {
+ super(collectEventsReceived);
+ }
+
+ @Before
+ public void setUpAndroid() throws Exception {
+ mainPoster = new EventPostHandler(Looper.getMainLooper());
+ assertFalse(Looper.getMainLooper().getThread().equals(Thread.currentThread()));
+ }
+
+ protected void postInMainThread(Object event) {
+ mainPoster.post(event);
+ }
+
+ @SuppressLint("HandlerLeak")
+ class EventPostHandler extends Handler {
+ public EventPostHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ eventBus.post(msg.obj);
+ }
+
+ void post(Object event) {
+ sendMessage(obtainMessage(0, event));
+ }
+
+ }
+
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/AndroidComponentsAvailabilityTest.java b/EventBusTest/src/org/greenrobot/eventbus/AndroidComponentsAvailabilityTest.java
new file mode 100644
index 00000000..15ae3d80
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/AndroidComponentsAvailabilityTest.java
@@ -0,0 +1,16 @@
+package org.greenrobot.eventbus;
+
+import org.greenrobot.eventbus.android.AndroidComponents;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class AndroidComponentsAvailabilityTest {
+
+ @Test
+ public void shouldBeAvailable() {
+ assertTrue(AndroidComponents.areAvailable());
+ assertNotNull(AndroidComponents.get());
+ }
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidActivityTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidActivityTest.java
new file mode 100644
index 00000000..364a3936
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidActivityTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+import android.app.Activity;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.rule.UiThreadTestRule;
+import android.util.Log;
+
+import org.junit.Rule;
+import org.junit.Test;
+
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Markus Junginger, greenrobot
+ */
+// Do not extend from AbstractAndroidEventBusTest, because it asserts test may not be in main thread
+public class EventBusAndroidActivityTest extends AbstractEventBusTest {
+
+ public static class WithIndex extends EventBusBasicTest {
+ @Test
+ public void dummy() {
+ }
+
+ }
+
+ @Rule
+ public final UiThreadTestRule uiThreadTestRule = new UiThreadTestRule();
+
+ @Test
+ @UiThreadTest
+ public void testRegisterAndPost() {
+ // Use an activity to test real life performance
+ TestActivity testActivity = new TestActivity();
+ String event = "Hello";
+
+ long start = System.currentTimeMillis();
+ eventBus.register(testActivity);
+ long time = System.currentTimeMillis() - start;
+ Log.d(EventBus.TAG, "Registered in " + time + "ms");
+
+ eventBus.post(event);
+
+ assertEquals(event, testActivity.lastStringEvent);
+ }
+
+ public static class TestActivity extends Activity {
+ public String lastStringEvent;
+
+ @Subscribe
+ public void onEvent(String event) {
+ lastStringEvent = event;
+ }
+ }
+
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidCancelEventDeliveryTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidCancelEventDeliveryTest.java
new file mode 100644
index 00000000..781ceda2
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidCancelEventDeliveryTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.support.test.runner.AndroidJUnit4;
+import android.test.UiThreadTest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(AndroidJUnit4.class)
+public class EventBusAndroidCancelEventDeliveryTest extends EventBusCancelEventDeliveryTest {
+
+ @UiThreadTest
+ @Test
+ public void testCancelInMainThread() {
+ SubscriberMainThread subscriber = new SubscriberMainThread();
+ eventBus.register(subscriber);
+ eventBus.post("42");
+ awaitLatch(subscriber.done, 10);
+ assertEquals(0, eventCount.intValue());
+ assertNotNull(failed);
+ }
+
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidMultithreadedTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidMultithreadedTest.java
new file mode 100644
index 00000000..8be31cc1
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidMultithreadedTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.greenrobot.eventbus;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import android.os.Looper;
+import android.support.test.runner.AndroidJUnit4;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+@RunWith(AndroidJUnit4.class)
+public class EventBusAndroidMultithreadedTest extends EventBusMultithreadedTest {
+
+ @Test
+ public void testSubscribeUnSubscribeAndPostMixedEventType() throws InterruptedException {
+ List threads = new ArrayList();
+
+ // Debug.startMethodTracing("testSubscribeUnSubscribeAndPostMixedEventType");
+ for (int i = 0; i < 5; i++) {
+ SubscribeUnsubscribeThread thread = new SubscribeUnsubscribeThread();
+ thread.start();
+ threads.add(thread);
+ }
+ // This test takes a bit longer, so just use fraction the regular count
+ runThreadsMixedEventType(COUNT / 4, 5);
+ for (SubscribeUnsubscribeThread thread : threads) {
+ thread.shutdown();
+ }
+ for (SubscribeUnsubscribeThread thread : threads) {
+ thread.join();
+ }
+ // Debug.stopMethodTracing();
+ }
+
+ public class SubscribeUnsubscribeThread extends Thread {
+ boolean running = true;
+
+ public void shutdown() {
+ running = false;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (running) {
+ eventBus.register(this);
+ double random = Math.random();
+ if (random > 0.6d) {
+ Thread.sleep(0, (int) (1000000 * Math.random()));
+ } else if (random > 0.3d) {
+ Thread.yield();
+ }
+ eventBus.unregister(this);
+ }
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onEventMainThread(String event) {
+ assertSame(Looper.getMainLooper(), Looper.myLooper());
+ }
+
+ @Subscribe(threadMode = ThreadMode.BACKGROUND)
+ public void onEventBackgroundThread(Integer event) {
+ assertNotSame(Looper.getMainLooper(), Looper.myLooper());
+ }
+
+ @Subscribe
+ public void onEvent(Object event) {
+ assertNotSame(Looper.getMainLooper(), Looper.myLooper());
+ }
+
+ @Subscribe(threadMode = ThreadMode.ASYNC)
+ public void onEventAsync(Object event) {
+ assertNotSame(Looper.getMainLooper(), Looper.myLooper());
+ }
+ }
+
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidOrderTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidOrderTest.java
new file mode 100644
index 00000000..ff348e1d
--- /dev/null
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusAndroidOrderTest.java
@@ -0,0 +1,91 @@
+package org.greenrobot.eventbus;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+
+import static org.junit.Assert.assertEquals;
+
+public class EventBusAndroidOrderTest extends AbstractAndroidEventBusTest {
+
+ private TestBackgroundPoster backgroundPoster;
+ private Handler handler;
+
+ @Before
+ public void setUp() throws Exception {
+ handler = new Handler(Looper.getMainLooper());
+ backgroundPoster = new TestBackgroundPoster(eventBus);
+ backgroundPoster.start();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ backgroundPoster.shutdown();
+ backgroundPoster.join();
+ }
+
+ @Test
+ public void backgroundAndMainUnordered() {
+ eventBus.register(this);
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ // post from non-main thread
+ backgroundPoster.post("non-main");
+ // post from main thread
+ eventBus.post("main");
+ }
+ });
+
+ waitForEventCount(2, 1000);
+
+ // observe that event from *main* thread is posted FIRST
+ // NOT in posting order
+ assertEquals("non-main", lastEvent);
+ }
+
+ @Test
+ public void backgroundAndMainOrdered() {
+ eventBus.register(this);
+
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ // post from non-main thread
+ backgroundPoster.post(new OrderedEvent("non-main"));
+ // post from main thread
+ eventBus.post(new OrderedEvent("main"));
+ }
+ });
+
+ waitForEventCount(2, 1000);
+
+ // observe that event from *main* thread is posted LAST
+ // IN posting order
+ assertEquals("main", ((OrderedEvent) lastEvent).thread);
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN)
+ public void onEvent(String event) {
+ trackEvent(event);
+ }
+
+ @Subscribe(threadMode = ThreadMode.MAIN_ORDERED)
+ public void onEvent(OrderedEvent event) {
+ trackEvent(event);
+ }
+
+ static class OrderedEvent {
+ String thread;
+
+ OrderedEvent(String thread) {
+ this.thread = thread;
+ }
+ }
+
+}
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusBackgroundThreadTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusBackgroundThreadTest.java
index 5a57f744..6ccb6025 100644
--- a/EventBusTest/src/org/greenrobot/eventbus/EventBusBackgroundThreadTest.java
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusBackgroundThreadTest.java
@@ -25,7 +25,7 @@
/**
* @author Markus Junginger, greenrobot
*/
-public class EventBusBackgroundThreadTest extends AbstractEventBusTest {
+public class EventBusBackgroundThreadTest extends AbstractAndroidEventBusTest {
@Test
public void testPostInCurrentThread() throws InterruptedException {
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadRacingTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadRacingTest.java
index a598220e..8ed637e8 100644
--- a/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadRacingTest.java
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadRacingTest.java
@@ -26,7 +26,7 @@
/**
* @author Markus Junginger, greenrobot
*/
-public class EventBusMainThreadRacingTest extends AbstractEventBusTest {
+public class EventBusMainThreadRacingTest extends AbstractAndroidEventBusTest {
private static final int ITERATIONS = LONG_TESTS ? 100000 : 1000;
diff --git a/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadTest.java b/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadTest.java
index 2195d10f..34c29ee6 100644
--- a/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadTest.java
+++ b/EventBusTest/src/org/greenrobot/eventbus/EventBusMainThreadTest.java
@@ -17,33 +17,15 @@
import android.os.Looper;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
-import java.util.ArrayList;
-import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* @author Markus Junginger, greenrobot
*/
-public class EventBusMainThreadTest extends AbstractEventBusTest {
-
- private BackgroundPoster backgroundPoster;
-
- @Before
- public void setUp() throws Exception {
- backgroundPoster = new BackgroundPoster();
- backgroundPoster.start();
- }
-
- @After
- public void tearDown() throws Exception {
- backgroundPoster.shutdown();
- backgroundPoster.join();
- }
+public class EventBusMainThreadTest extends AbstractAndroidEventBusTest {
@Test
public void testPost() throws InterruptedException {
@@ -57,11 +39,17 @@ public void testPost() throws InterruptedException {
@Test
public void testPostInBackgroundThread() throws InterruptedException {
+ TestBackgroundPoster backgroundPoster = new TestBackgroundPoster(eventBus);
+ backgroundPoster.start();
+
eventBus.register(this);
backgroundPoster.post("Hello");
waitForEventCount(1, 1000);
assertEquals("Hello", lastEvent);
assertEquals(Looper.getMainLooper().getThread(), lastThread);
+
+ backgroundPoster.shutdown();
+ backgroundPoster.join();
}
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -69,68 +57,4 @@ public void onEventMainThread(String event) {
trackEvent(event);
}
- class BackgroundPoster extends Thread {
- volatile boolean running = true;
- private final List