RepoPilotOpen in app →

greenrobot/EventBus

Event bus for Android and Java that simplifies communication between Activities, Fragments, Threads, Services, etc. Less code, better quality.

Healthy

Healthy across all four use cases

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • 5 active contributors
  • Apache-2.0 licensed
  • CI configured
Show all 6 evidence items →
  • Tests present
  • Stale — last commit 2y ago
  • Single-maintainer risk — top contributor 81% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/greenrobot/eventbus)](https://repopilot.app/r/greenrobot/eventbus)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/greenrobot/eventbus on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: greenrobot/EventBus

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/greenrobot/EventBus shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across all four use cases

  • 5 active contributors
  • Apache-2.0 licensed
  • CI configured
  • Tests present
  • ⚠ Stale — last commit 2y ago
  • ⚠ Single-maintainer risk — top contributor 81% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live greenrobot/EventBus repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/greenrobot/EventBus.

What it runs against: a local clone of greenrobot/EventBus — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in greenrobot/EventBus | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 837 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>greenrobot/EventBus</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of greenrobot/EventBus. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/greenrobot/EventBus.git
#   cd EventBus
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of greenrobot/EventBus and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "greenrobot/EventBus(\\.git)?\\b" \\
  && ok "origin remote is greenrobot/EventBus" \\
  || miss "origin remote is not greenrobot/EventBus (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "EventBus/src/org/greenrobot/eventbus/EventBus.java" \\
  && ok "EventBus/src/org/greenrobot/eventbus/EventBus.java" \\
  || miss "missing critical file: EventBus/src/org/greenrobot/eventbus/EventBus.java"
test -f "EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java" \\
  && ok "EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java" \\
  || miss "missing critical file: EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java"
test -f "EventBus/src/org/greenrobot/eventbus/Subscribe.java" \\
  && ok "EventBus/src/org/greenrobot/eventbus/Subscribe.java" \\
  || miss "missing critical file: EventBus/src/org/greenrobot/eventbus/Subscribe.java"
test -f "EventBus/src/org/greenrobot/eventbus/ThreadMode.java" \\
  && ok "EventBus/src/org/greenrobot/eventbus/ThreadMode.java" \\
  || miss "missing critical file: EventBus/src/org/greenrobot/eventbus/ThreadMode.java"
test -f "EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java" \\
  && ok "EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java" \\
  || miss "missing critical file: EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 837 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~807d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/greenrobot/EventBus"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

EventBus is a publish/subscribe (pub/sub) event bus library for Android and Java that decouples event producers from consumers through asynchronous message delivery. It allows components (Activities, Fragments, Services, background threads) to communicate without direct dependencies by posting events that are routed to all registered subscribers based on event type and optional delivery thread constraints. At ~60KB, it eliminates boilerplate for inter-component messaging while supporting advanced features like thread mode control, subscriber priorities, and dead event handling. Dual-module Gradle structure: EventBus/ contains core pub/sub engine with org.greenrobot.eventbus.* package (EventBus.java as entry point, AsyncPoster/BackgroundPoster for thread dispatch, SubscriberMethodFinder for reflection-based registration). EventBusAnnotationProcessor/ is a compile-time annotation processor generating subscriber indices to avoid reflection overhead. EventBus/src/org/greenrobot/eventbus/android/ adds Android lifecycle awareness (AndroidComponents, AndroidDependenciesDetector). EventBus/src/org/greenrobot/eventbus/meta/ defines compile-time subscriber metadata contracts.

👥Who it's for

Android developers building multi-component apps (Activities, Fragments, Services, background threads) who need event-driven architecture without complex callback hierarchies or dependency injection frameworks. Also used by Java backend developers needing lightweight pub/sub for thread-safe event distribution. Maintainers at greenrobot actively support production apps with 1B+ installs.

🌱Maturity & risk

Highly mature and production-ready. Version 3.3.1 is stable and widely deployed in high-scale Android apps. The codebase shows professional quality with CI/CD via GitHub Actions (.github/workflows/gradle.yml), annotation processor for compile-time optimization, and dual packaging (Android and Java variants). Active maintenance indicated by recent documentation and dual-module support, though recent commit frequency data is not visible—typical of stable, feature-complete libraries.

Low risk overall. Single module + annotation processor structure is simple and auditable. No visible heavy external dependencies (Java 1.8+ target is minimal). Main risk is single maintainer (greenrobot team) for a widely-used library, but proven track record and corporate backing mitigate this. No breaking changes visible in current codebase structure; API surface is intentionally small.

Active areas of work

Active maintenance mode. Library supports subscriber index generation via annotation processor (EventBusAnnotationProcessor) to reduce reflection overhead—this is the recommended path forward per README. Android-specific components (AndroidComponents.java, AndroidDependenciesDetector.java) maintain lifecycle-aware integration. Focus appears to be on stability and tooling rather than new features; no major rework visible in file structure.

🚀Get running

git clone https://github.com/greenrobot/EventBus.git
cd EventBus
# View structure
ls -la EventBus/src/org/greenrobot/eventbus/
# Build with Gradle (build.gradle present in EventBus/ and EventBusAnnotationProcessor/)
./gradlew build
# For Android project: add to build.gradle: implementation("org.greenrobot:eventbus:3.3.1")
# For Java project: implementation("org.greenrobot:eventbus-java:3.3.1")

Daily commands: No server/runtime to start—EventBus is a library. Use in your own app: EventBus.getDefault().post(new MyEvent()) triggers delivery. For development/testing, invoke Gradle: ./gradlew build compiles both EventBus module and annotation processor. See EventBusPerformance/ for benchmark app (Android-specific). Example flow: (1) define event class, (2) @Subscribe-annotate handler method, (3) register via EventBus.getDefault().register(this) in lifecycle start, (4) post events from anywhere.

🗺️Map of the codebase

  • EventBus/src/org/greenrobot/eventbus/EventBus.java — Core event bus singleton managing event posting, subscriber registration, and delivery orchestration—the entry point for all pub/sub operations.
  • EventBus/src/org/greenrobot/eventbus/SubscriberMethodFinder.java — Reflection-based scanner that discovers @Subscribe-annotated methods on registered objects, supporting both indexed and fallback reflection modes.
  • EventBus/src/org/greenrobot/eventbus/Subscribe.java — Annotation that marks event handler methods; defines thread mode, priority, and sticky event behavior—contributors must understand subscription contracts.
  • EventBus/src/org/greenrobot/eventbus/ThreadMode.java — Enum specifying delivery execution contexts (POSTING, MAIN, BACKGROUND, ASYNC); critical for understanding thread-safety guarantees.
  • EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java — Compile-time annotation processor that generates SubscriberInfo indices to eliminate reflection overhead in production builds.
  • EventBus/src/org/greenrobot/eventbus/EventBusBuilder.java — Fluent builder for EventBus configuration; controls logging, exception handling, thread pool policies, and indexed subscriber lookup.
  • EventBus/src/org/greenrobot/eventbus/Poster.java — Interface abstracted by AsyncPoster, BackgroundPoster, and MainThreadSupport; responsible for event delivery mechanics across threads.

🛠️How to make changes

Add a new event type and handler

  1. Create a plain Java class to represent your event (no annotations required) (YourEventClass.java)
  2. In any class where you want to handle the event, add a public method annotated with @Subscribe from EventBus/src/org/greenrobot/eventbus/Subscribe.java, specifying threadMode if non-default (EventBus/src/org/greenrobot/eventbus/Subscribe.java)
  3. Register the subscriber instance with EventBus.getDefault().register(this) in your component's init or onCreate() (EventBus/src/org/greenrobot/eventbus/EventBus.java)
  4. Post the event from anywhere with EventBus.getDefault().post(new YourEventClass(...)) (EventBus/src/org/greenrobot/eventbus/EventBus.java)
  5. Unregister in cleanup (onDestroy) via EventBus.getDefault().unregister(this) (EventBus/src/org/greenrobot/eventbus/EventBus.java)

Enable compile-time subscriber indexing for production

  1. Add EventBusAnnotationProcessor as an annotation processor dependency in your gradle build (EventBusAnnotationProcessor/build.gradle)
  2. The processor will generate a SubscriberInfoIndex implementation at compile time for all @Subscribe methods (EventBusAnnotationProcessor/src/org/greenrobot/eventbus/annotationprocessor/EventBusAnnotationProcessor.java)
  3. Configure EventBus via EventBusBuilder to add the generated index class, eliminating reflection overhead (EventBus/src/org/greenrobot/eventbus/EventBusBuilder.java)
  4. The builder's addIndex() method registers your generated SubscriberInfoIndex implementation (EventBus/src/org/greenrobot/eventbus/meta/SubscriberInfoIndex.java)

Customize thread delivery and error handling

  1. Choose a ThreadMode on your @Subscribe annotation: POSTING (caller's thread), MAIN (UI thread), BACKGROUND (shared bg thread), or ASYNC (thread pool) (EventBus/src/org/greenrobot/eventbus/ThreadMode.java)
  2. Create an EventBusBuilder to override default logging and exception handlers (EventBus/src/org/greenrobot/eventbus/EventBusBuilder.java)
  3. Call builder.logSubscriberExceptions() and builder.sendSubscriberExceptionEvent() to control error reporting (EventBus/src/org/greenrobot/eventbus/EventBusBuilder.java)
  4. Subscribe to SubscriberExceptionEvent to handle subscriber failures, or NoSubscriberEvent for unhandled posts (EventBus/src/org/greenrobot/eventbus/SubscriberExceptionEvent.java)

🔧Why these technologies

  • Java reflection + compile-time annotation processing — Enables zero-configuration subscriber discovery with optional performance optimization via generated indices; balances convenience and production performance
  • Thread pools (ExecutorService) and single-threaded queues (PendingPostQueue) — Provides flexible thread-mode delivery (POSTING, MAIN, BACKGROUND, ASYNC) with predictable scheduling and low contention
  • Android MainLooper detection (MainThreadSupport) — Abstracts Android-specific UI thread posting without forcing Android dependency for non-Android Java applications
  • Event-driven error reporting (SubscriberEx — undefined

🪤Traps & gotchas

Reflection overhead by default: SubscriberMethodFinder uses reflection at runtime; README heavily recommends using EventBusAnnotationProcessor to pre-generate subscriber indices and avoid this cost. Sticky events: post(event, true) persists the last event of each type; subscribers registered after posting still receive it—easy to forget and cause memory leaks or unexpected behavior. Register/unregister lifecycle: Forgetting to unregister in onStop() (Android) causes memory leaks; must pair register/unregister in lifecycle methods. MainThreadSupport detection: Android detection in AndroidDependenciesDetector.java is automatic but can fail if Android SDK is not detected in classpath—non-obvious on build environment changes. PendingPost object reuse: PendingPostQueue reuses PendingPost instances; don't hold references across posts.

🏗️Architecture

💡Concepts to learn

  • Pub/Sub Event Bus — Core architectural pattern this library implements; understanding loose coupling between producers and consumers is essential to use EventBus correctly.
  • Sticky Events — EventBus-specific feature allowing late subscribers to receive the last event of a type; can cause subtle bugs if not understood, especially around lifecycle and memory.
  • Annotation Processing (Compile-time) — EventBusAnnotationProcessor generates subscriber indices at compile time rather than using reflection at runtime; critical optimization for performance-sensitive apps.
  • ThreadMode / Thread Dispatch — EventBus decouples not just components but also execution threads (POSTING, MAIN, ASYNC, BACKGROUND); incorrect choice causes deadlocks or main-thread blocking.
  • Reflection for Method Discovery — Default subscriber discovery uses reflection to find @Subscribe methods; expensive on Android; annotation processor replaces this with generated index.
  • Producer Consumer Pattern / Queue — PendingPostQueue implements thread-safe event queue; understanding queue semantics and concurrent access prevents race conditions in async posting.
  • Android Lifecycle Awareness — EventBus integrates with Android activity/fragment lifecycle via register/unregister hooks; critical for memory management and preventing leaks in Android apps.
  • square/otto — Legacy EventBus alternative for Android (now unmaintained); greenrobot's EventBus is the modern successor with better performance and thread control.
  • Google/guava — Guava EventBus provides similar pub/sub for Java; greenrobot EventBus is lighter (~60KB) and Android-optimized with annotation processor support.
  • ReactiveX/RxJava — RxJava offers reactive streams and complex event chains; EventBus is simpler for basic pub/sub without learning reactive operators.
  • greenrobot/greenDAO — Companion library by same maintainer; ORM for Android database access often used alongside EventBus for database change notifications.
  • greenrobot-team/greenrobot-examples — Official example applications demonstrating EventBus patterns and best practices in real Android/Java projects.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for SubscriberMethodFinder.java

SubscriberMethodFinder.java is a critical component that discovers and caches subscriber methods via reflection. Currently, there are no visible dedicated test files for this core functionality in the repository. This component has complex logic around annotation parsing, method filtering, and caching that deserves thorough unit test coverage to prevent regressions.

  • [ ] Create EventBusTest/src/org/greenrobot/eventbus/SubscriberMethodFinderTest.java
  • [ ] Add tests for method discovery with various @Subscribe configurations (ThreadMode, priority, sticky)
  • [ ] Add tests for caching behavior and cache invalidation
  • [ ] Add tests for edge cases: invalid subscriber methods, inheritance hierarchies, interface implementations
  • [ ] Add tests for performance characteristics of the finder

Add integration tests for Android-specific components (AndroidComponents.java, MainThreadSupport.java)

The repository has Android-specific code in EventBus/src/org/greenrobot/eventbus/android/ that handles main thread detection and Android component lifecycle. However, there's no visible test module that validates this Android integration works correctly across different Android API levels and scenarios. This is critical for the library's core use case.

  • [ ] Create EventBusTest/src/org/greenrobot/eventbus/android/AndroidMainThreadTest.java
  • [ ] Add tests for MainThreadSupport detection and initialization
  • [ ] Add tests for posting events on main thread vs background threads on Android
  • [ ] Add tests for AndroidComponents integration with Activity/Fragment lifecycle
  • [ ] Configure gradle.yml to run Android instrumentation tests on multiple API levels

Add unit tests for exception handling paths (SubscriberExceptionEvent.java, EventBusException.java)

The codebase has defined exception handling with SubscriberExceptionEvent and EventBusException, but there are no visible tests validating error scenarios like subscriber method failures, exception propagation, and NoSubscriberEvent generation. This is critical for reliability.

  • [ ] Create EventBusTest/src/org/greenrobot/eventbus/ExceptionHandlingTest.java
  • [ ] Add tests for subscriber methods that throw exceptions and how EventBus handles them
  • [ ] Add tests for NoSubscriberEvent generation when no subscribers exist
  • [ ] Add tests for SubscriberExceptionEvent posting behavior
  • [ ] Add tests for different ThreadMode behaviors when exceptions occur
  • [ ] Add tests for exception handling with AsyncPoster and BackgroundPoster

🌿Good first issues

  • Add comprehensive unit tests for PendingPostQueue.java (thread-safe queue implementation). Currently no dedicated test file visible; add tests for enqueue/dequeue under concurrent load with multiple posters.: Event queue correctness is critical; gaps in test coverage for concurrent scenarios could hide race conditions.
  • Expand JavaDoc for ThreadMode enum values (POSTING, MAIN, ASYNC, BACKGROUND) with concrete Android/Java examples showing when to use each. Current docs are sparse.: ThreadMode choice is the most common source of bugs; examples would help new users avoid deadlocks and main-thread blocking.
  • Add integration test demonstrating annotation processor usage (EventBusAnnotationProcessor) with a sample app that verifies subscriber index generation and reflection-free dispatch.: README recommends annotation processor but no visible end-to-end test validates the compile-time optimization path works correctly.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 0194926 — CI: use temurin for JDK, update checkout and setup-java to v3. (greenrobot-team)
  • 842a4a3 — fix typo (guoci)
  • a74cdf0 — Document MAIN_ORDERED behavior if not Android. (greenrobot-team)
  • 6f939ca — README: fix subscriber method snippet. (greenrobot-team)
  • c799332 — Prepare release 3.3.1 (greenrobot-team)
  • 7013bc2 — Merge pull request #686 from greenrobot/685-failure-event-fixes (greenrobot-team)
  • eba6809 — Make EventBusPerformance build again (project outdated though) (greenrobot-team)
  • 60c4b78 — AsyncExecutor: use lambda. (greenrobot-team)
  • 757bc9a — AsyncExecutor: update docs with event class requirements, ProGuard rule tip. (greenrobot-team)
  • 9f4d2ec — Fix ProGuard rules to keep default failure event class constructor. (greenrobot-team)

🔒Security observations

The EventBus codebase demonstrates good security posture overall. It is a lightweight publish/subscribe library with a focused scope and minimal external dependencies. No critical vulnerabilities were identified. The primary concerns are low-severity build configuration practices. The codebase lacks obvious injection vectors (no database operations, web requests, or HTML rendering visible in the provided structure). No hardcoded credentials, API keys, or sensitive configuration files were identified. The Java source compatibility targets Java 1.8+, which is relatively modern. Recommendations include implementing dependency version pinning and enabling stricter build verification. The library's architecture inherently mitigates many common attack vectors due to its limited scope (event bus pattern implementation).

  • Low · Javadoc Generation with failOnError Disabled — EventBus/build.gradle (javadoc task). The build.gradle file sets 'failOnError = false' for javadoc generation. While this allows builds to succeed even with javadoc errors, it may mask documentation issues that could hide security-relevant API documentation problems. Fix: Consider enabling javadoc error checking in CI/CD pipelines to ensure documentation quality. Use 'failOnError = true' or configure selective exclusions for known issues.
  • Low · No Explicit Dependency Version Pinning in Build Configuration — EventBus/build.gradle (gradle plugin configuration). The provided build.gradle does not show explicit version pinning for build plugins or dependencies. The 'apply from' pattern for publish.gradle suggests external configuration inheritance, which could introduce version drift or unexpected plugin behavior if not carefully managed. Fix: Explicitly pin versions for all build plugins and dependencies. Use dependency locking (gradle.lockfile) to ensure reproducible builds and prevent supply chain risks.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · greenrobot/EventBus — RepoPilot