├── .github └── workflows │ └── gradle.yml ├── .gitignore ├── COMPARISON.md ├── CONTRIBUTING.md ├── EventBus-Publish-Subscribe.png ├── EventBus ├── build.gradle └── src │ └── org │ └── greenrobot │ └── eventbus │ ├── AsyncPoster.java │ ├── BackgroundPoster.java │ ├── EventBus.java │ ├── EventBusBuilder.java │ ├── EventBusException.java │ ├── Logger.java │ ├── MainThreadSupport.java │ ├── NoSubscriberEvent.java │ ├── PendingPost.java │ ├── PendingPostQueue.java │ ├── Poster.java │ ├── Subscribe.java │ ├── SubscriberExceptionEvent.java │ ├── SubscriberMethod.java │ ├── SubscriberMethodFinder.java │ ├── Subscription.java │ ├── ThreadMode.java │ ├── android │ ├── AndroidComponents.java │ └── AndroidDependenciesDetector.java │ ├── meta │ ├── AbstractSubscriberInfo.java │ ├── SimpleSubscriberInfo.java │ ├── SubscriberInfo.java │ ├── SubscriberInfoIndex.java │ └── SubscriberMethodInfo.java │ └── util │ ├── AsyncExecutor.java │ ├── ExceptionToResourceMapping.java │ ├── HasExecutionScope.java │ └── ThrowableFailureEvent.java ├── EventBusAnnotationProcessor ├── build.gradle ├── res │ └── META-INF │ │ └── services │ │ └── javax.annotation.processing.Processor └── src │ └── org │ └── greenrobot │ └── eventbus │ └── annotationprocessor │ └── EventBusAnnotationProcessor.java ├── EventBusPerformance ├── .gitignore ├── AndroidManifest.xml ├── build.gradle ├── proguard-project.txt ├── project.properties ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-ldpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── layout │ │ ├── activity_runtests.xml │ │ └── activity_setuptests.xml │ └── values │ │ └── strings.xml └── src │ └── org │ └── greenrobot │ └── eventbusperf │ ├── Test.java │ ├── TestEvent.java │ ├── TestFinishedEvent.java │ ├── TestParams.java │ ├── TestRunner.java │ ├── TestRunnerActivity.java │ ├── TestSetupActivity.java │ └── testsubject │ ├── PerfTestEventBus.java │ ├── PerfTestOtto.java │ └── SubscribeClassEventBusDefault.java ├── EventBusTest ├── AndroidManifest.xml ├── build.gradle ├── libs │ └── EventBusTestSubscriberInJar-3.0.0.jar └── src │ └── org │ └── greenrobot │ └── eventbus │ ├── AbstractAndroidEventBusTest.java │ ├── AndroidComponentsAvailabilityTest.java │ ├── ClassMapPerfTest.java │ ├── EventBusAndroidActivityTest.java │ ├── EventBusAndroidCancelEventDeliveryTest.java │ ├── EventBusAndroidMultithreadedTest.java │ ├── EventBusAndroidOrderTest.java │ ├── EventBusBackgroundThreadTest.java │ ├── EventBusMainThreadRacingTest.java │ ├── EventBusMainThreadTest.java │ ├── EventBusMethodModifiersTest.java │ ├── TestBackgroundPoster.java │ └── indexed │ ├── EventBusAndroidOrderTestWithIndex.java │ ├── EventBusBackgroundThreadTestWithIndex.java │ ├── EventBusBasicTestWithIndex.java │ ├── EventBusCancelEventDeliveryTestWithIndex.java │ ├── EventBusFallbackToReflectionTestWithIndex.java │ ├── EventBusGenericsTestWithIndex.java │ ├── EventBusInheritanceDisabledTestWithIndex.java │ ├── EventBusInheritanceTestWithIndex.java │ ├── EventBusMainThreadRacingTestWithIndex.java │ ├── EventBusMainThreadTestWithIndex.java │ ├── EventBusMethodModifiersTestWithIndex.java │ ├── EventBusMultithreadedTestWithIndex.java │ ├── EventBusNoSubscriberEventTestWithIndex.java │ ├── EventBusOrderedSubscriptionsTestWithIndex.java │ ├── EventBusRegistrationRacingTestWithIndex.java │ ├── EventBusStickyEventTestWithIndex.java │ ├── EventBusSubscriberExceptionTestWithIndex.java │ ├── EventBusSubscriberInJarTestWithIndex.java │ └── Indexed.java ├── EventBusTestJava ├── build.gradle ├── libs │ └── EventBusTestSubscriberInJar-3.0.0.jar └── src │ └── main │ └── java │ └── org │ └── greenrobot │ └── eventbus │ ├── AbstractEventBusTest.java │ ├── EventBusBasicTest.java │ ├── EventBusBuilderTest.java │ ├── EventBusCancelEventDeliveryTest.java │ ├── EventBusFallbackToReflectionTest.java │ ├── EventBusGenericsTest.java │ ├── EventBusIndexTest.java │ ├── EventBusInheritanceDisabledSubclassNoMethod.java │ ├── EventBusInheritanceDisabledSubclassTest.java │ ├── EventBusInheritanceDisabledTest.java │ ├── EventBusInheritanceSubclassNoMethodTest.java │ ├── EventBusInheritanceSubclassTest.java │ ├── EventBusInheritanceTest.java │ ├── EventBusMultithreadedTest.java │ ├── EventBusNoSubscriberEventTest.java │ ├── EventBusOrderedSubscriptionsTest.java │ ├── EventBusRegistrationRacingTest.java │ ├── EventBusStickyEventTest.java │ ├── EventBusSubscriberExceptionTest.java │ ├── EventBusSubscriberInJarTest.java │ ├── EventBusSubscriberLegalTest.java │ └── IntTestEvent.java ├── EventBusTestSubscriberInJar ├── build.gradle └── src │ └── org │ └── greenrobot │ └── eventbus │ └── SubscriberInJar.java ├── LICENSE ├── README.md ├── build.gradle ├── eventbus-android ├── .gitignore ├── README.md ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── greenrobot │ └── eventbus │ ├── HandlerPoster.java │ └── android │ ├── AndroidComponentsImpl.java │ ├── AndroidLogger.java │ └── DefaultAndroidMainThreadSupport.java ├── gradle ├── publish.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── javadoc-style ├── background.gif └── stylesheet.css └── settings.gradle /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Gradle 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle 3 | 4 | name: Java CI with Gradle 5 | 6 | on: 7 | push: 8 | pull_request: 9 | 10 | jobs: 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v3 17 | - name: Set up JDK 11 18 | uses: actions/setup-java@v3 19 | with: 20 | java-version: '11' 21 | distribution: 'temurin' 22 | cache: gradle 23 | - name: Grant execute permission for gradlew 24 | run: chmod +x gradlew 25 | - name: Gradle Info 26 | run: ./gradlew -version 27 | - name: Build with Gradle 28 | run: ./gradlew build 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | release/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | gradle.properties 20 | 21 | # Local configuration file (sdk path, etc) 22 | local.properties 23 | 24 | # IntelliJ project files 25 | *.iml 26 | .idea/ 27 | 28 | # Eclipse project files 29 | .settings/ 30 | 31 | # Misc 32 | .DS_Store 33 | -------------------------------------------------------------------------------- /COMPARISON.md: -------------------------------------------------------------------------------- 1 | EventBus Comparison 2 | =================== 3 | 4 | Comparison with Square's Otto 5 | ----------------------------- 6 | Otto is another event bus library for Android; actually it's a fork of Guava's EventBus. greenrobot's EventBus and Otto share some basic semantics (register, post, unregister, ...), but there are differences which the following table summarizes: 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 |
EventBusOtto
Declare event handling methodsAnnotations (since 3.0, can be precompiled for best performance)Annotations
Event inheritanceYesYes
Subscriber inheritanceYesNo
Cache most recent eventsYes, sticky eventsNo
Event producers (e.g. for coding cached events)NoYes
Event delivery in posting threadYes (Default)Yes
Event delivery in main threadYesNo
Event delivery in background threadYesNo
Asynchronous event deliveryYesNo
59 | 60 | _**Note:** the following information is outdated, preprocessed annotations are much faster than EventBus 2.x, on which the following table is based._ 61 | 62 | Besides features, performance is another differentiator. To compare performance, we created an Android application, which is also part of this repository (EventBusPerformance). You can also run the app on your phone to benchmark different scenarios. 63 | 64 | TODO: Update for EventBus 3 with and without index. 65 | 66 | Benchmark results indicate that EventBus is significantly faster in almost every scenario: 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
EventBusOtto
Posting 1000 events, Android 2.3 emulator~70% faster
Posting 1000 events, S3 Android 4.0~110% faster
Register 1000 subscribers, Android 2.3 emulator~10% faster
Register 1000 subscribers, S3 Android 4.0~70% faster
Register subscribers cold start, Android 2.3 emulator~350% faster
Register subscribers cold start, S3 Android 4.0About the same
103 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Before you create an Issue... 2 | ============================= 3 | 4 | There are better Places for Support 5 | ----------------------------------- 6 | We want your question to be answered, so it is important that you ask at the right place. Be aware that an issue tracker is not the best place to ask for support. An issue tracker is used to track issues (bugs or feature requests). 7 | Instead, please use [stackoverflow.com](https://stackoverflow.com/questions/tagged/greenrobot-eventbus?sort=frequent) and use the tag [greenrobot-eventbus](http://stackoverflow.com/tags/greenrobot-eventbus/info) for your question. 8 | 9 | If you want professional support, check http://greenrobot.org/contact-support/. 10 | 11 | Examples for support questions that are more likely to be answered on StackOverflow: 12 | 13 | * Asking how something works 14 | * Asking how to use EventBus in a specific scenario 15 | * Your app crashes/misbehaves and you are not sure why 16 | 17 | The perfect Issue Report 18 | ------------------------ 19 | A couple of simple steps can save time for everyone. 20 | 21 | Check before reporting: 22 | 23 | * It's not a support inquiry 24 | * You have read the docs 25 | * You searched the web and stackoverflow 26 | * You searched existing issues to avoid duplicates 27 | 28 | Reporting bugs: 29 | 30 | * Please investigate if is the bug is really caused by the library. Isolate the issue: what's the minimal code to reproduce the bug? 31 | * Bonus steps to gain extra karma points: once you isolated and identified the issue, you can prepare an push request. Submit an unit test causing the bug, and ideally a fix for the bug. 32 | 33 | Requesting features: 34 | 35 | * Ask yourself: is the feature useful for a majority users? One of our major goals is to keep the API simple and concise. We do not want to cover all possible use cases, but those that make 80% of users happy. 36 | 37 | A Note on Pull Requests 38 | ======================= 39 | Pull requests (and issues) may queue up up a bit. Usually, pull requests and issues are checked when new releases are planned. 40 | 41 | For bigger pull requests, it's a good idea to check with the maintainer upfront about the idea and the implementation outline. 42 | 43 | Thanks for reading! 44 | =================== 45 | It's your contributions and feedback that makes maintaining this library fun. 46 | -------------------------------------------------------------------------------- /EventBus-Publish-Subscribe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenrobot/EventBus/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBus-Publish-Subscribe.png -------------------------------------------------------------------------------- /EventBus/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = rootProject.group 4 | version = rootProject.version 5 | 6 | java.sourceCompatibility = JavaVersion.VERSION_1_8 7 | java.targetCompatibility = JavaVersion.VERSION_1_8 8 | 9 | sourceSets { 10 | main { 11 | java { 12 | srcDir 'src' 13 | // exclude 'de/greenrobot/event/util/**' 14 | } 15 | } 16 | } 17 | 18 | javadoc { 19 | failOnError = false 20 | title = "EventBus ${version} API" 21 | options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2012-2020 greenrobot.org. All Rights Reserved.' 22 | } 23 | 24 | task javadocJar(type: Jar, dependsOn: javadoc) { 25 | archiveClassifier.set("javadoc") 26 | from 'build/docs/javadoc' 27 | } 28 | 29 | task sourcesJar(type: Jar) { 30 | archiveClassifier.set("sources") 31 | from sourceSets.main.allSource 32 | } 33 | 34 | apply from: rootProject.file("gradle/publish.gradle") 35 | // Set project-specific properties 36 | afterEvaluate { 37 | publishing.publications { 38 | mavenJava(MavenPublication) { 39 | artifactId = "eventbus-java" 40 | 41 | from components.java 42 | artifact javadocJar 43 | artifact sourcesJar 44 | pom { 45 | name = "EventBus" 46 | description = "EventBus is a publish/subscribe event bus." 47 | packaging = "jar" 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/AsyncPoster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | 19 | /** 20 | * Posts events in background. 21 | * 22 | * @author Markus 23 | */ 24 | class AsyncPoster implements Runnable, Poster { 25 | 26 | private final PendingPostQueue queue; 27 | private final EventBus eventBus; 28 | 29 | AsyncPoster(EventBus eventBus) { 30 | this.eventBus = eventBus; 31 | queue = new PendingPostQueue(); 32 | } 33 | 34 | public void enqueue(Subscription subscription, Object event) { 35 | PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); 36 | queue.enqueue(pendingPost); 37 | eventBus.getExecutorService().execute(this); 38 | } 39 | 40 | @Override 41 | public void run() { 42 | PendingPost pendingPost = queue.poll(); 43 | if(pendingPost == null) { 44 | throw new IllegalStateException("No pending post available"); 45 | } 46 | eventBus.invokeSubscriber(pendingPost); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/BackgroundPoster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import java.util.logging.Level; 19 | 20 | /** 21 | * Posts events in background. 22 | * 23 | * @author Markus 24 | */ 25 | final class BackgroundPoster implements Runnable, Poster { 26 | 27 | private final PendingPostQueue queue; 28 | private final EventBus eventBus; 29 | 30 | private volatile boolean executorRunning; 31 | 32 | BackgroundPoster(EventBus eventBus) { 33 | this.eventBus = eventBus; 34 | queue = new PendingPostQueue(); 35 | } 36 | 37 | public void enqueue(Subscription subscription, Object event) { 38 | PendingPost pendingPost = PendingPost.obtainPendingPost(subscription, event); 39 | synchronized (this) { 40 | queue.enqueue(pendingPost); 41 | if (!executorRunning) { 42 | executorRunning = true; 43 | eventBus.getExecutorService().execute(this); 44 | } 45 | } 46 | } 47 | 48 | @Override 49 | public void run() { 50 | try { 51 | try { 52 | while (true) { 53 | PendingPost pendingPost = queue.poll(1000); 54 | if (pendingPost == null) { 55 | synchronized (this) { 56 | // Check again, this time in synchronized 57 | pendingPost = queue.poll(); 58 | if (pendingPost == null) { 59 | executorRunning = false; 60 | return; 61 | } 62 | } 63 | } 64 | eventBus.invokeSubscriber(pendingPost); 65 | } 66 | } catch (InterruptedException e) { 67 | eventBus.getLogger().log(Level.WARNING, Thread.currentThread().getName() + " was interrupted", e); 68 | } 69 | } finally { 70 | executorRunning = false; 71 | } 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/EventBusException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * An {@link RuntimeException} thrown in cases something went wrong inside EventBus. 20 | * 21 | * @author Markus 22 | * 23 | */ 24 | public class EventBusException extends RuntimeException { 25 | 26 | private static final long serialVersionUID = -2912559384646531479L; 27 | 28 | public EventBusException(String detailMessage) { 29 | super(detailMessage); 30 | } 31 | 32 | public EventBusException(Throwable throwable) { 33 | super(throwable); 34 | } 35 | 36 | public EventBusException(String detailMessage, Throwable throwable) { 37 | super(detailMessage, throwable); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/Logger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2020 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import org.greenrobot.eventbus.android.AndroidComponents; 19 | import java.util.logging.Level; 20 | 21 | public interface Logger { 22 | 23 | void log(Level level, String msg); 24 | 25 | void log(Level level, String msg, Throwable th); 26 | 27 | class JavaLogger implements Logger { 28 | protected final java.util.logging.Logger logger; 29 | 30 | public JavaLogger(String tag) { 31 | logger = java.util.logging.Logger.getLogger(tag); 32 | } 33 | 34 | @Override 35 | public void log(Level level, String msg) { 36 | // TODO Replace logged method with caller method 37 | logger.log(level, msg); 38 | } 39 | 40 | @Override 41 | public void log(Level level, String msg, Throwable th) { 42 | // TODO Replace logged method with caller method 43 | logger.log(level, msg, th); 44 | } 45 | 46 | } 47 | 48 | class SystemOutLogger implements Logger { 49 | 50 | @Override 51 | public void log(Level level, String msg) { 52 | System.out.println("[" + level + "] " + msg); 53 | } 54 | 55 | @Override 56 | public void log(Level level, String msg, Throwable th) { 57 | System.out.println("[" + level + "] " + msg); 58 | th.printStackTrace(System.out); 59 | } 60 | 61 | } 62 | 63 | class Default { 64 | public static Logger get() { 65 | if (AndroidComponents.areAvailable()) { 66 | return AndroidComponents.get().logger; 67 | } 68 | 69 | return new SystemOutLogger(); 70 | } 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/MainThreadSupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * Interface to the "main" thread, which can be whatever you like. Typically on Android, Android's main thread is used. 20 | */ 21 | public interface MainThreadSupport { 22 | 23 | boolean isMainThread(); 24 | 25 | Poster createPoster(EventBus eventBus); 26 | } 27 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/NoSubscriberEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * This Event is posted by EventBus when no subscriber is found for a posted event. 20 | * 21 | * @author Markus 22 | */ 23 | public final class NoSubscriberEvent { 24 | /** The {@link EventBus} instance to with the original event was posted to. */ 25 | public final EventBus eventBus; 26 | 27 | /** The original event that could not be delivered to any subscriber. */ 28 | public final Object originalEvent; 29 | 30 | public NoSubscriberEvent(EventBus eventBus, Object originalEvent) { 31 | this.eventBus = eventBus; 32 | this.originalEvent = originalEvent; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/PendingPost.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import java.util.ArrayList; 19 | import java.util.List; 20 | 21 | final class PendingPost { 22 | private final static List pendingPostPool = new ArrayList(); 23 | 24 | Object event; 25 | Subscription subscription; 26 | PendingPost next; 27 | 28 | private PendingPost(Object event, Subscription subscription) { 29 | this.event = event; 30 | this.subscription = subscription; 31 | } 32 | 33 | static PendingPost obtainPendingPost(Subscription subscription, Object event) { 34 | synchronized (pendingPostPool) { 35 | int size = pendingPostPool.size(); 36 | if (size > 0) { 37 | PendingPost pendingPost = pendingPostPool.remove(size - 1); 38 | pendingPost.event = event; 39 | pendingPost.subscription = subscription; 40 | pendingPost.next = null; 41 | return pendingPost; 42 | } 43 | } 44 | return new PendingPost(event, subscription); 45 | } 46 | 47 | static void releasePendingPost(PendingPost pendingPost) { 48 | pendingPost.event = null; 49 | pendingPost.subscription = null; 50 | pendingPost.next = null; 51 | synchronized (pendingPostPool) { 52 | // Don't let the pool grow indefinitely 53 | if (pendingPostPool.size() < 10000) { 54 | pendingPostPool.add(pendingPost); 55 | } 56 | } 57 | } 58 | 59 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/PendingPostQueue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus; 18 | 19 | final class PendingPostQueue { 20 | private PendingPost head; 21 | private PendingPost tail; 22 | 23 | synchronized void enqueue(PendingPost pendingPost) { 24 | if (pendingPost == null) { 25 | throw new NullPointerException("null cannot be enqueued"); 26 | } 27 | if (tail != null) { 28 | tail.next = pendingPost; 29 | tail = pendingPost; 30 | } else if (head == null) { 31 | head = tail = pendingPost; 32 | } else { 33 | throw new IllegalStateException("Head present, but no tail"); 34 | } 35 | notifyAll(); 36 | } 37 | 38 | synchronized PendingPost poll() { 39 | PendingPost pendingPost = head; 40 | if (head != null) { 41 | head = head.next; 42 | if (head == null) { 43 | tail = null; 44 | } 45 | } 46 | return pendingPost; 47 | } 48 | 49 | synchronized PendingPost poll(int maxMillisToWait) throws InterruptedException { 50 | if (head == null) { 51 | wait(maxMillisToWait); 52 | } 53 | return poll(); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/Poster.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * Posts events. 20 | * 21 | * @author William Ferguson 22 | */ 23 | public interface Poster { 24 | 25 | /** 26 | * Enqueue an event to be posted for a particular subscription. 27 | * 28 | * @param subscription Subscription which will receive the event. 29 | * @param event Event that will be posted to subscribers. 30 | */ 31 | void enqueue(Subscription subscription, Object event); 32 | } 33 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/Subscribe.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus; 18 | 19 | 20 | import java.lang.annotation.Documented; 21 | import java.lang.annotation.ElementType; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | @Documented 27 | @Retention(RetentionPolicy.RUNTIME) 28 | @Target({ElementType.METHOD}) 29 | public @interface Subscribe { 30 | ThreadMode threadMode() default ThreadMode.POSTING; 31 | 32 | /** 33 | * If true, delivers the most recent sticky event (posted with 34 | * {@link EventBus#postSticky(Object)}) to this subscriber (if event available). 35 | */ 36 | boolean sticky() default false; 37 | 38 | /** Subscriber priority to influence the order of event delivery. 39 | * Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before 40 | * others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of 41 | * delivery among subscribers with different {@link ThreadMode}s! */ 42 | int priority() default 0; 43 | } 44 | 45 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/SubscriberExceptionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * This Event is posted by EventBus when an exception occurs inside a subscriber's event handling method. 20 | * 21 | * @author Markus 22 | */ 23 | public final class SubscriberExceptionEvent { 24 | /** The {@link EventBus} instance to with the original event was posted to. */ 25 | public final EventBus eventBus; 26 | 27 | /** The Throwable thrown by a subscriber. */ 28 | public final Throwable throwable; 29 | 30 | /** The original event that could not be delivered to any subscriber. */ 31 | public final Object causingEvent; 32 | 33 | /** The subscriber that threw the Throwable. */ 34 | public final Object causingSubscriber; 35 | 36 | public SubscriberExceptionEvent(EventBus eventBus, Throwable throwable, Object causingEvent, 37 | Object causingSubscriber) { 38 | this.eventBus = eventBus; 39 | this.throwable = throwable; 40 | this.causingEvent = causingEvent; 41 | this.causingSubscriber = causingSubscriber; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/SubscriberMethod.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | import java.lang.reflect.Method; 19 | 20 | /** Used internally by EventBus and generated subscriber indexes. */ 21 | public class SubscriberMethod { 22 | final Method method; 23 | final ThreadMode threadMode; 24 | final Class eventType; 25 | final int priority; 26 | final boolean sticky; 27 | /** Used for efficient comparison */ 28 | String methodString; 29 | 30 | public SubscriberMethod(Method method, Class eventType, ThreadMode threadMode, int priority, boolean sticky) { 31 | this.method = method; 32 | this.threadMode = threadMode; 33 | this.eventType = eventType; 34 | this.priority = priority; 35 | this.sticky = sticky; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object other) { 40 | if (other == this) { 41 | return true; 42 | } else if (other instanceof SubscriberMethod) { 43 | checkMethodString(); 44 | SubscriberMethod otherSubscriberMethod = (SubscriberMethod)other; 45 | otherSubscriberMethod.checkMethodString(); 46 | // Don't use method.equals because of http://code.google.com/p/android/issues/detail?id=7811#c6 47 | return methodString.equals(otherSubscriberMethod.methodString); 48 | } else { 49 | return false; 50 | } 51 | } 52 | 53 | private synchronized void checkMethodString() { 54 | if (methodString == null) { 55 | // Method.toString has more overhead, just take relevant parts of the method 56 | StringBuilder builder = new StringBuilder(64); 57 | builder.append(method.getDeclaringClass().getName()); 58 | builder.append('#').append(method.getName()); 59 | builder.append('(').append(eventType.getName()); 60 | methodString = builder.toString(); 61 | } 62 | } 63 | 64 | @Override 65 | public int hashCode() { 66 | return method.hashCode(); 67 | } 68 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/Subscription.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | final class Subscription { 19 | final Object subscriber; 20 | final SubscriberMethod subscriberMethod; 21 | /** 22 | * Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery 23 | * {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions. 24 | */ 25 | volatile boolean active; 26 | 27 | Subscription(Object subscriber, SubscriberMethod subscriberMethod) { 28 | this.subscriber = subscriber; 29 | this.subscriberMethod = subscriberMethod; 30 | active = true; 31 | } 32 | 33 | @Override 34 | public boolean equals(Object other) { 35 | if (other instanceof Subscription) { 36 | Subscription otherSubscription = (Subscription) other; 37 | return subscriber == otherSubscription.subscriber 38 | && subscriberMethod.equals(otherSubscription.subscriberMethod); 39 | } else { 40 | return false; 41 | } 42 | } 43 | 44 | @Override 45 | public int hashCode() { 46 | return subscriber.hashCode() + subscriberMethod.methodString.hashCode(); 47 | } 48 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/ThreadMode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus; 17 | 18 | /** 19 | * Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus. 20 | * EventBus takes care of threading independently of the posting thread. 21 | * 22 | * @see EventBus#register(Object) 23 | */ 24 | public enum ThreadMode { 25 | /** 26 | * This is the default. Subscriber will be called directly in the same thread, which is posting the event. Event delivery 27 | * implies the least overhead because it avoids thread switching completely. Thus, this is the recommended mode for 28 | * simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers 29 | * using this mode must return quickly to avoid blocking the posting thread, which may be the main thread. 30 | */ 31 | POSTING, 32 | 33 | /** 34 | * On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is 35 | * the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event 36 | * is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread. 37 | *

38 | * If not on Android, behaves the same as {@link #POSTING}. 39 | */ 40 | MAIN, 41 | 42 | /** 43 | * On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN}, 44 | * the event will always be queued for delivery. This ensures that the post call is non-blocking. 45 | *

46 | * If not on Android, behaves the same as {@link #POSTING}. 47 | */ 48 | MAIN_ORDERED, 49 | 50 | /** 51 | * On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods 52 | * will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single 53 | * background thread, that will deliver all its events sequentially. Subscribers using this mode should try to 54 | * return quickly to avoid blocking the background thread. 55 | *

56 | * If not on Android, always uses a background thread. 57 | */ 58 | BACKGROUND, 59 | 60 | /** 61 | * Subscriber will be called in a separate thread. This is always independent of the posting thread and the 62 | * main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should 63 | * use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number 64 | * of long-running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus 65 | * uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications. 66 | */ 67 | ASYNC 68 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/android/AndroidComponents.java: -------------------------------------------------------------------------------- 1 | package org.greenrobot.eventbus.android; 2 | 3 | import org.greenrobot.eventbus.Logger; 4 | import org.greenrobot.eventbus.MainThreadSupport; 5 | 6 | public abstract class AndroidComponents { 7 | 8 | private static final AndroidComponents implementation; 9 | 10 | static { 11 | implementation = AndroidDependenciesDetector.isAndroidSDKAvailable() 12 | ? AndroidDependenciesDetector.instantiateAndroidComponents() 13 | : null; 14 | } 15 | 16 | public static boolean areAvailable() { 17 | return implementation != null; 18 | } 19 | 20 | public static AndroidComponents get() { 21 | return implementation; 22 | } 23 | 24 | public final Logger logger; 25 | public final MainThreadSupport defaultMainThreadSupport; 26 | 27 | public AndroidComponents(Logger logger, MainThreadSupport defaultMainThreadSupport) { 28 | this.logger = logger; 29 | this.defaultMainThreadSupport = defaultMainThreadSupport; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/android/AndroidDependenciesDetector.java: -------------------------------------------------------------------------------- 1 | package org.greenrobot.eventbus.android; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | 6 | @SuppressWarnings("TryWithIdenticalCatches") 7 | public class AndroidDependenciesDetector { 8 | 9 | public static boolean isAndroidSDKAvailable() { 10 | 11 | try { 12 | Class looperClass = Class.forName("android.os.Looper"); 13 | Method getMainLooper = looperClass.getDeclaredMethod("getMainLooper"); 14 | Object mainLooper = getMainLooper.invoke(null); 15 | return mainLooper != null; 16 | } 17 | catch (ClassNotFoundException ignored) {} 18 | catch (NoSuchMethodException ignored) {} 19 | catch (IllegalAccessException ignored) {} 20 | catch (InvocationTargetException ignored) {} 21 | 22 | return false; 23 | } 24 | 25 | private static final String ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME = "org.greenrobot.eventbus.android.AndroidComponentsImpl"; 26 | 27 | public static boolean areAndroidComponentsAvailable() { 28 | 29 | try { 30 | Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME); 31 | return true; 32 | } 33 | catch (ClassNotFoundException ex) { 34 | return false; 35 | } 36 | } 37 | 38 | public static AndroidComponents instantiateAndroidComponents() { 39 | 40 | try { 41 | Class impl = Class.forName(ANDROID_COMPONENTS_IMPLEMENTATION_CLASS_NAME); 42 | return (AndroidComponents) impl.getConstructor().newInstance(); 43 | } 44 | catch (Throwable ex) { 45 | return null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/meta/AbstractSubscriberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.EventBusException; 19 | import org.greenrobot.eventbus.SubscriberMethod; 20 | import org.greenrobot.eventbus.ThreadMode; 21 | 22 | import java.lang.reflect.Method; 23 | 24 | /** Base class for generated subscriber meta info classes created by annotation processing. */ 25 | public abstract class AbstractSubscriberInfo implements SubscriberInfo { 26 | private final Class subscriberClass; 27 | private final Class superSubscriberInfoClass; 28 | private final boolean shouldCheckSuperclass; 29 | 30 | protected AbstractSubscriberInfo(Class subscriberClass, Class superSubscriberInfoClass, 31 | boolean shouldCheckSuperclass) { 32 | this.subscriberClass = subscriberClass; 33 | this.superSubscriberInfoClass = superSubscriberInfoClass; 34 | this.shouldCheckSuperclass = shouldCheckSuperclass; 35 | } 36 | 37 | @Override 38 | public Class getSubscriberClass() { 39 | return subscriberClass; 40 | } 41 | 42 | @Override 43 | public SubscriberInfo getSuperSubscriberInfo() { 44 | if(superSubscriberInfoClass == null) { 45 | return null; 46 | } 47 | try { 48 | return superSubscriberInfoClass.newInstance(); 49 | } catch (InstantiationException e) { 50 | throw new RuntimeException(e); 51 | } catch (IllegalAccessException e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | 56 | @Override 57 | public boolean shouldCheckSuperclass() { 58 | return shouldCheckSuperclass; 59 | } 60 | 61 | protected SubscriberMethod createSubscriberMethod(String methodName, Class eventType) { 62 | return createSubscriberMethod(methodName, eventType, ThreadMode.POSTING, 0, false); 63 | } 64 | 65 | protected SubscriberMethod createSubscriberMethod(String methodName, Class eventType, ThreadMode threadMode) { 66 | return createSubscriberMethod(methodName, eventType, threadMode, 0, false); 67 | } 68 | 69 | protected SubscriberMethod createSubscriberMethod(String methodName, Class eventType, ThreadMode threadMode, 70 | int priority, boolean sticky) { 71 | try { 72 | Method method = subscriberClass.getDeclaredMethod(methodName, eventType); 73 | return new SubscriberMethod(method, eventType, threadMode, priority, sticky); 74 | } catch (NoSuchMethodException e) { 75 | throw new EventBusException("Could not find subscriber method in " + subscriberClass + 76 | ". Maybe a missing ProGuard rule?", e); 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/meta/SimpleSubscriberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.SubscriberMethod; 19 | 20 | /** 21 | * Uses {@link SubscriberMethodInfo} objects to create {@link org.greenrobot.eventbus.SubscriberMethod} objects on demand. 22 | */ 23 | public class SimpleSubscriberInfo extends AbstractSubscriberInfo { 24 | 25 | private final SubscriberMethodInfo[] methodInfos; 26 | 27 | public SimpleSubscriberInfo(Class subscriberClass, boolean shouldCheckSuperclass, SubscriberMethodInfo[] methodInfos) { 28 | super(subscriberClass, null, shouldCheckSuperclass); 29 | this.methodInfos = methodInfos; 30 | } 31 | 32 | @Override 33 | public synchronized SubscriberMethod[] getSubscriberMethods() { 34 | int length = methodInfos.length; 35 | SubscriberMethod[] methods = new SubscriberMethod[length]; 36 | for (int i = 0; i < length; i++) { 37 | SubscriberMethodInfo info = methodInfos[i]; 38 | methods[i] = createSubscriberMethod(info.methodName, info.eventType, info.threadMode, 39 | info.priority, info.sticky); 40 | } 41 | return methods; 42 | } 43 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/meta/SubscriberInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.SubscriberMethod; 19 | 20 | /** Base class for generated index classes created by annotation processing. */ 21 | public interface SubscriberInfo { 22 | Class getSubscriberClass(); 23 | 24 | SubscriberMethod[] getSubscriberMethods(); 25 | 26 | SubscriberInfo getSuperSubscriberInfo(); 27 | 28 | boolean shouldCheckSuperclass(); 29 | } 30 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/meta/SubscriberInfoIndex.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | /** 19 | * Interface for generated indexes. 20 | */ 21 | public interface SubscriberInfoIndex { 22 | SubscriberInfo getSubscriberInfo(Class subscriberClass); 23 | } 24 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/meta/SubscriberMethodInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.meta; 17 | 18 | import org.greenrobot.eventbus.ThreadMode; 19 | 20 | public class SubscriberMethodInfo { 21 | final String methodName; 22 | final ThreadMode threadMode; 23 | final Class eventType; 24 | final int priority; 25 | final boolean sticky; 26 | 27 | public SubscriberMethodInfo(String methodName, Class eventType, ThreadMode threadMode, 28 | int priority, boolean sticky) { 29 | this.methodName = methodName; 30 | this.threadMode = threadMode; 31 | this.eventType = eventType; 32 | this.priority = priority; 33 | this.sticky = sticky; 34 | } 35 | 36 | public SubscriberMethodInfo(String methodName, Class eventType) { 37 | this(methodName, eventType, ThreadMode.POSTING, 0, false); 38 | } 39 | 40 | public SubscriberMethodInfo(String methodName, Class eventType, ThreadMode threadMode) { 41 | this(methodName, eventType, threadMode, 0, false); 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/util/AsyncExecutor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.util; 17 | 18 | import org.greenrobot.eventbus.EventBus; 19 | 20 | import java.lang.reflect.Constructor; 21 | import java.util.concurrent.Executor; 22 | import java.util.concurrent.Executors; 23 | import java.util.logging.Level; 24 | 25 | /** 26 | * Executes an {@link RunnableEx} using a thread pool. Thrown exceptions are propagated by posting failure events. 27 | * By default, uses {@link ThrowableFailureEvent}. 28 | *

29 | * Set a custom event type using {@link Builder#failureEventType(Class)}. 30 | * The failure event class must have a constructor with one parameter of type {@link Throwable}. 31 | * If using ProGuard or R8 make sure the constructor of the failure event class is kept, it is accessed via reflection. 32 | * E.g. add a rule like 33 | *

 34 |  * -keepclassmembers class com.example.CustomThrowableFailureEvent {
 35 |  *     <init>(java.lang.Throwable);
 36 |  * }
 37 |  * 
38 | */ 39 | public class AsyncExecutor { 40 | 41 | public static class Builder { 42 | private Executor threadPool; 43 | private Class failureEventType; 44 | private EventBus eventBus; 45 | 46 | private Builder() { 47 | } 48 | 49 | public Builder threadPool(Executor threadPool) { 50 | this.threadPool = threadPool; 51 | return this; 52 | } 53 | 54 | public Builder failureEventType(Class failureEventType) { 55 | this.failureEventType = failureEventType; 56 | return this; 57 | } 58 | 59 | public Builder eventBus(EventBus eventBus) { 60 | this.eventBus = eventBus; 61 | return this; 62 | } 63 | 64 | public AsyncExecutor build() { 65 | return buildForScope(null); 66 | } 67 | 68 | public AsyncExecutor buildForScope(Object executionContext) { 69 | if (eventBus == null) { 70 | eventBus = EventBus.getDefault(); 71 | } 72 | if (threadPool == null) { 73 | threadPool = Executors.newCachedThreadPool(); 74 | } 75 | if (failureEventType == null) { 76 | failureEventType = ThrowableFailureEvent.class; 77 | } 78 | return new AsyncExecutor(threadPool, eventBus, failureEventType, executionContext); 79 | } 80 | } 81 | 82 | /** Like {@link Runnable}, but the run method may throw an exception. */ 83 | public interface RunnableEx { 84 | void run() throws Exception; 85 | } 86 | 87 | public static Builder builder() { 88 | return new Builder(); 89 | } 90 | 91 | public static AsyncExecutor create() { 92 | return new Builder().build(); 93 | } 94 | 95 | private final Executor threadPool; 96 | private final Constructor failureEventConstructor; 97 | private final EventBus eventBus; 98 | private final Object scope; 99 | 100 | private AsyncExecutor(Executor threadPool, EventBus eventBus, Class failureEventType, Object scope) { 101 | this.threadPool = threadPool; 102 | this.eventBus = eventBus; 103 | this.scope = scope; 104 | try { 105 | failureEventConstructor = failureEventType.getConstructor(Throwable.class); 106 | } catch (NoSuchMethodException e) { 107 | throw new RuntimeException( 108 | "Failure event class must have a constructor with one parameter of type Throwable", e); 109 | } 110 | } 111 | 112 | /** Posts an failure event if the given {@link RunnableEx} throws an Exception. */ 113 | public void execute(final RunnableEx runnable) { 114 | threadPool.execute(() -> { 115 | try { 116 | runnable.run(); 117 | } catch (Exception e) { 118 | Object event; 119 | try { 120 | event = failureEventConstructor.newInstance(e); 121 | } catch (Exception e1) { 122 | eventBus.getLogger().log(Level.SEVERE, "Original exception:", e); 123 | throw new RuntimeException("Could not create failure event", e1); 124 | } 125 | if (event instanceof HasExecutionScope) { 126 | ((HasExecutionScope) event).setExecutionScope(scope); 127 | } 128 | eventBus.post(event); 129 | } 130 | }); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/util/ExceptionToResourceMapping.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2020 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus.util; 18 | 19 | import org.greenrobot.eventbus.Logger; 20 | 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | import java.util.Map.Entry; 24 | import java.util.Set; 25 | import java.util.logging.Level; 26 | 27 | 28 | /** 29 | * Maps throwables to texts for error dialogs. Use Config to configure the mapping. 30 | * 31 | * @author Markus 32 | */ 33 | public class ExceptionToResourceMapping { 34 | 35 | public final Map, Integer> throwableToMsgIdMap; 36 | 37 | public ExceptionToResourceMapping() { 38 | throwableToMsgIdMap = new HashMap<>(); 39 | } 40 | 41 | /** Looks at the exception and its causes trying to find an ID. */ 42 | public Integer mapThrowable(final Throwable throwable) { 43 | Throwable throwableToCheck = throwable; 44 | int depthToGo = 20; 45 | 46 | while (true) { 47 | Integer resId = mapThrowableFlat(throwableToCheck); 48 | if (resId != null) { 49 | return resId; 50 | } else { 51 | throwableToCheck = throwableToCheck.getCause(); 52 | depthToGo--; 53 | if (depthToGo <= 0 || throwableToCheck == throwable || throwableToCheck == null) { 54 | Logger logger = Logger.Default.get(); // No EventBus instance here 55 | logger.log(Level.FINE, "No specific message resource ID found for " + throwable); 56 | // return config.defaultErrorMsgId; 57 | return null; 58 | } 59 | } 60 | } 61 | 62 | } 63 | 64 | /** Mapping without checking the cause (done in mapThrowable). */ 65 | protected Integer mapThrowableFlat(Throwable throwable) { 66 | Class throwableClass = throwable.getClass(); 67 | Integer resId = throwableToMsgIdMap.get(throwableClass); 68 | if (resId == null) { 69 | Class closestClass = null; 70 | Set, Integer>> mappings = throwableToMsgIdMap.entrySet(); 71 | for (Entry, Integer> mapping : mappings) { 72 | Class candidate = mapping.getKey(); 73 | if (candidate.isAssignableFrom(throwableClass)) { 74 | if (closestClass == null || closestClass.isAssignableFrom(candidate)) { 75 | closestClass = candidate; 76 | resId = mapping.getValue(); 77 | } 78 | } 79 | } 80 | 81 | } 82 | return resId; 83 | } 84 | 85 | public ExceptionToResourceMapping addMapping(Class clazz, int msgId) { 86 | throwableToMsgIdMap.put(clazz, msgId); 87 | return this; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/util/HasExecutionScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.greenrobot.eventbus.util; 18 | 19 | public interface HasExecutionScope { 20 | Object getExecutionScope(); 21 | 22 | void setExecutionScope(Object executionScope); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /EventBus/src/org/greenrobot/eventbus/util/ThrowableFailureEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2012-2016 Markus Junginger, greenrobot (http://greenrobot.org) 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.greenrobot.eventbus.util; 17 | 18 | /** 19 | * A generic failure event, which can be used by apps to propagate thrown exceptions. 20 | * Used as default failure event by {@link AsyncExecutor}. 21 | */ 22 | public class ThrowableFailureEvent implements HasExecutionScope { 23 | protected final Throwable throwable; 24 | protected final boolean suppressErrorUi; 25 | private Object executionContext; 26 | 27 | public ThrowableFailureEvent(Throwable throwable) { 28 | this.throwable = throwable; 29 | suppressErrorUi = false; 30 | } 31 | 32 | /** 33 | * @param suppressErrorUi 34 | * true indicates to the receiver that no error UI (e.g. dialog) should now displayed. 35 | */ 36 | public ThrowableFailureEvent(Throwable throwable, boolean suppressErrorUi) { 37 | this.throwable = throwable; 38 | this.suppressErrorUi = suppressErrorUi; 39 | } 40 | 41 | public Throwable getThrowable() { 42 | return throwable; 43 | } 44 | 45 | public boolean isSuppressErrorUi() { 46 | return suppressErrorUi; 47 | } 48 | 49 | public Object getExecutionScope() { 50 | return executionContext; 51 | } 52 | 53 | public void setExecutionScope(Object executionContext) { 54 | this.executionContext = executionContext; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /EventBusAnnotationProcessor/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java' 2 | 3 | group = rootProject.group 4 | version = rootProject.version 5 | 6 | java.sourceCompatibility = JavaVersion.VERSION_1_8 7 | java.targetCompatibility = JavaVersion.VERSION_1_8 8 | 9 | dependencies { 10 | implementation project(':eventbus-java') 11 | implementation 'de.greenrobot:java-common:2.3.1' 12 | 13 | // Generates the required META-INF descriptor to make the processor incremental. 14 | def incap = '0.2' 15 | compileOnly "net.ltgt.gradle.incap:incap:$incap" 16 | annotationProcessor "net.ltgt.gradle.incap:incap-processor:$incap" 17 | } 18 | 19 | sourceSets { 20 | main { 21 | java { 22 | srcDir 'src' 23 | } 24 | resources { 25 | srcDir 'res' 26 | } 27 | } 28 | } 29 | 30 | javadoc { 31 | title = "EventBus Annotation Processor ${version} API" 32 | options.bottom = 'Available under the Apache License, Version 2.0 - Copyright © 2015-2020 greenrobot.org. All Rights Reserved.' 33 | } 34 | 35 | task javadocJar(type: Jar, dependsOn: javadoc) { 36 | archiveClassifier.set("javadoc") 37 | from 'build/docs/javadoc' 38 | } 39 | 40 | task sourcesJar(type: Jar) { 41 | archiveClassifier.set("sources") 42 | from sourceSets.main.allSource 43 | } 44 | 45 | apply from: rootProject.file("gradle/publish.gradle") 46 | // Set project-specific properties 47 | afterEvaluate { 48 | publishing.publications { 49 | mavenJava(MavenPublication) { 50 | artifactId = "eventbus-annotation-processor" 51 | 52 | from components.java 53 | artifact javadocJar 54 | artifact sourcesJar 55 | pom { 56 | name = "EventBus Annotation Processor" 57 | description = "Precompiler for EventBus Annotations." 58 | packaging = "jar" 59 | } 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /EventBusAnnotationProcessor/res/META-INF/services/javax.annotation.processing.Processor: -------------------------------------------------------------------------------- 1 | org.greenrobot.eventbus.annotationprocessor.EventBusAnnotationProcessor 2 | -------------------------------------------------------------------------------- /EventBusPerformance/.gitignore: -------------------------------------------------------------------------------- 1 | /bin 2 | /gen 3 | -------------------------------------------------------------------------------- /EventBusPerformance/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | 9 | 12 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /EventBusPerformance/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | // Note: IntelliJ IDEA 2021.1 only supports up to version 4.1 9 | classpath 'com.android.tools.build:gradle:4.1.3' 10 | } 11 | } 12 | 13 | apply plugin: 'com.android.application' 14 | 15 | dependencies { 16 | implementation project(':eventbus-android') 17 | annotationProcessor project(':eventbus-annotation-processor') 18 | implementation 'com.squareup:otto:1.3.8' 19 | } 20 | 21 | android { 22 | compileSdkVersion _compileSdkVersion 23 | 24 | sourceSets { 25 | main { 26 | manifest.srcFile 'AndroidManifest.xml' 27 | java.srcDirs = ['src'] 28 | res.srcDirs = ['res'] 29 | } 30 | } 31 | 32 | defaultConfig { 33 | minSdkVersion 7 34 | targetSdkVersion 26 35 | versionCode 1 36 | versionName "2.0.0" 37 | javaCompileOptions { 38 | annotationProcessorOptions { 39 | arguments = [eventBusIndex: 'org.greenrobot.eventbusperf.MyEventBusIndex'] 40 | } 41 | } 42 | } 43 | 44 | compileOptions { 45 | sourceCompatibility JavaVersion.VERSION_1_8 46 | targetCompatibility JavaVersion.VERSION_1_8 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /EventBusPerformance/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /EventBusPerformance/project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}\tools\proguard\proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-17 15 | -------------------------------------------------------------------------------- /EventBusPerformance/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenrobot/EventBus/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBusPerformance/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /EventBusPerformance/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenrobot/EventBus/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBusPerformance/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /EventBusPerformance/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenrobot/EventBus/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBusPerformance/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /EventBusPerformance/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/greenrobot/EventBus/0194926b3bcf70cc0d7bfd3c5da16708dd5ab876/EventBusPerformance/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /EventBusPerformance/res/layout/activity_runtests.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 19 | 20 | 26 | 27 | 32 | 33 | 34 |