RepoPilotOpen in app →

koush/AndroidAsync

Asynchronous socket, http(s) (client+server) and websocket library for android. Based on nio, not threads.

Mixed

Stale — last commit 3y ago

weakest axis
Use as dependencyConcerns

non-standard license (Other); last commit was 3y ago…

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-isMixed

last commit was 3y ago; no CI workflows detected

  • 3 active contributors
  • Other licensed
  • Tests present
Show all 8 evidence items →
  • Stale — last commit 3y ago
  • Small team — 3 contributors active in recent commits
  • Single-maintainer risk — top contributor 97% of recent commits
  • Non-standard license (Other) — review terms
  • No CI workflows detected
What would change the summary?
  • Use as dependency ConcernsMixed if: clarify license terms
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days

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 "Forkable" badge

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

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/koush/androidasync?axis=fork)](https://repopilot.app/r/koush/androidasync)

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/koush/androidasync on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: koush/AndroidAsync

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/koush/AndroidAsync 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

WAIT — Stale — last commit 3y ago

  • 3 active contributors
  • Other licensed
  • Tests present
  • ⚠ Stale — last commit 3y ago
  • ⚠ Small team — 3 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 97% of recent commits
  • ⚠ Non-standard license (Other) — review terms
  • ⚠ No CI workflows detected

<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 koush/AndroidAsync repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/koush/AndroidAsync.

What it runs against: a local clone of koush/AndroidAsync — 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 koush/AndroidAsync | Confirms the artifact applies here, not a fork | | 2 | License is still Other | 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 ≤ 1292 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>koush/AndroidAsync</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of koush/AndroidAsync. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/koush/AndroidAsync.git
#   cd AndroidAsync
#
# 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 koush/AndroidAsync and re-run."
  exit 2
fi

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

# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
  && ok "license is Other" \\
  || miss "license drift — was Other 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 "AndroidAsync/src/com/koushikdutta/async/AsyncServer.java" \\
  && ok "AndroidAsync/src/com/koushikdutta/async/AsyncServer.java" \\
  || miss "missing critical file: AndroidAsync/src/com/koushikdutta/async/AsyncServer.java"
test -f "AndroidAsync/src/com/koushikdutta/async/SelectorWrapper.java" \\
  && ok "AndroidAsync/src/com/koushikdutta/async/SelectorWrapper.java" \\
  || miss "missing critical file: AndroidAsync/src/com/koushikdutta/async/SelectorWrapper.java"
test -f "AndroidAsync/src/com/koushikdutta/async/future/Future.java" \\
  && ok "AndroidAsync/src/com/koushikdutta/async/future/Future.java" \\
  || miss "missing critical file: AndroidAsync/src/com/koushikdutta/async/future/Future.java"
test -f "AndroidAsync/src/com/koushikdutta/async/DataEmitter.java" \\
  && ok "AndroidAsync/src/com/koushikdutta/async/DataEmitter.java" \\
  || miss "missing critical file: AndroidAsync/src/com/koushikdutta/async/DataEmitter.java"
test -f "AndroidAsync/src/com/koushikdutta/async/ByteBufferList.java" \\
  && ok "AndroidAsync/src/com/koushikdutta/async/ByteBufferList.java" \\
  || miss "missing critical file: AndroidAsync/src/com/koushikdutta/async/ByteBufferList.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 1292 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1262d)"
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/koush/AndroidAsync"
  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

AndroidAsync is a low-level, NIO-based asynchronous networking library for Android that provides non-blocking socket, HTTP(S) client/server, and WebSocket implementations with a single-threaded, callback-driven architecture. It powers higher-level libraries like Ion and enables raw protocol-level networking without spawning threads, using Java NIO selectors under the hood. Dual-module structure: AndroidAsync/ contains the core Java NIO implementation (AsyncServer, AsyncSocket, AsyncNetworkSocket, AsyncSSLSocket, etc. in src/com/koushikdutta/async/), while AndroidAsync-Kotlin/ wraps it with Kotlin extensions (FutureExtensions.kt). Both modules compile to separate AAR libraries targeting minSdkVersion 14.

👥Who it's for

Android library developers and framework authors who need fine-grained control over network I/O (especially for custom protocols, bidirectional communication, or server-side socket handling), and maintainers of higher-level HTTP clients like Ion who build on top of AndroidAsync's core.

🌱Maturity & risk

This project is mature and production-ready but shows signs of being in maintenance mode rather than active feature development. The core Java codebase (667KB) is well-established, but recent activity appears limited—no visible CI/CD pipeline in the file list, and the Kotlin wrapper (AndroidAsync-Kotlin) is minimal (1.5KB). It lacks comprehensive test coverage visible in the file structure.

Risk is moderate: single maintainer (koush) with no visible CI pipeline, no recent commit dates in the provided data, and minimal test infrastructure shown in the repository structure. The library's low-level NIO nature means bugs can have serious concurrency implications. However, it's been battle-tested in Ion and other production Android apps, mitigating some risk.

Active areas of work

No active development signals are visible in the provided file list. The repository appears to be in a stable, mature state with no PRs, active branches, or recent changes indicated. The Kotlin module suggests past modernization efforts but limited ongoing work.

🚀Get running

git clone https://github.com/koush/AndroidAsync.git
cd AndroidAsync
./gradlew build
# Or to use in a project:
# Add to build.gradle: implementation 'com.koushikdutta.async:androidasync:2.+'

Daily commands:

# Build the library
./gradlew build
# Run tests (if available)
./gradlew test
# For Kotlin module with instrumented tests
./gradlew :AndroidAsync-Kotlin:connectedAndroidTest

🗺️Map of the codebase

  • AndroidAsync/src/com/koushikdutta/async/AsyncServer.java — Core NIO-based event loop and server orchestration; the foundation of all async operations and socket handling
  • AndroidAsync/src/com/koushikdutta/async/SelectorWrapper.java — Wraps Java NIO Selector; manages non-blocking I/O event multiplexing for all socket operations
  • AndroidAsync/src/com/koushikdutta/async/future/Future.java — Primary async abstraction; all async operations return Futures that enable cancellation and chaining
  • AndroidAsync/src/com/koushikdutta/async/DataEmitter.java — Event-driven data stream abstraction; defines callback interface for pushing data through the pipeline
  • AndroidAsync/src/com/koushikdutta/async/ByteBufferList.java — Efficient buffer management for NIO operations; minimizes allocations in the hot path
  • AndroidAsync/src/com/koushikdutta/async/http — HTTP client and server implementation; layers protocol parsing on top of raw sockets
  • AndroidAsync/build.gradle — Build configuration and dependency declarations; defines API levels and Kotlin interop

🛠️How to make changes

Add a Custom Protocol Handler

  1. Create a FilteredDataEmitter subclass that parses your protocol from the raw byte stream (AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java)
  2. Implement onDataAvailable() to decode frames/messages and call downstream DataCallback (AndroidAsync/src/com/koushikdutta/async/DataEmitter.java)
  3. Register your emitter in a ConnectCallback after socket connects (AndroidAsync/src/com/koushikdutta/async/callback/ConnectCallback.java)
  4. Chain additional filters (compression, serialization) by wrapping FilteredDataEmitter (AndroidAsync/src/com/koushikdutta/async/FilteredDataEmitter.java)

Build an HTTP Server Endpoint

  1. Call AsyncServer.listen() with a port and ListenCallback (AndroidAsync/src/com/koushikdutta/async/AsyncServer.java)
  2. In ListenCallback, accept the socket and wrap with HttpServerRequestCallback (AndroidAsync/src/com/koushikdutta/async/http)
  3. In HttpServerRequestCallback, inspect request and write response via DataSink (AndroidAsync/src/com/koushikdutta/async/DataSink.java)
  4. Return Future from callback for lifecycle management; cancel on client disconnect (AndroidAsync/src/com/koushikdutta/async/future/Future.java)

Make an Async HTTP Request

  1. Call AsyncHttpClient.getDefaultInstance() to get or create the shared client (AndroidAsync/src/com/koushikdutta/async/http)
  2. Build an AsyncHttpRequest (method, URL, headers, body) (AndroidAsync/src/com/koushikdutta/async/http)
  3. Execute with execute(request, callback) to get a Future<AsyncHttpResponse> (AndroidAsync/src/com/koushikdutta/async/http)
  4. Chain callbacks via future.setCallback() or future.then() for response handling (AndroidAsync/src/com/koushikdutta/async/future/Future.java)

Implement Custom Flow Control

  1. Override onDataAvailable() in your emitter; call pause() to stop receiving data (AndroidAsync/src/com/koushikdutta/async/DataEmitterBase.java)
  2. Batch or buffer data; call resume() when ready to process more (AndroidAsync/src/com/koushikdutta/async/DataEmitterBase.java)
  3. Wire a WritableCallback to know when the socket is ready for writes (AndroidAsync/src/com/koushikdutta/async/callback/WritableCallback.java)
  4. Combine pause/resume with AsyncServer.post() for external backpressure control (AndroidAsync/src/com/koushikdutta/async/AsyncServer.java)

🪤Traps & gotchas

NIO selector affinity: all operations on a socket must occur on the AsyncServer's event loop thread—blocking calls or accessing sockets from other threads will deadlock. ByteBufferList.recycle() must be called explicitly to avoid memory leaks in high-volume scenarios. SSL handshakes are async but context-switching overhead can impact latency. minSdkVersion 14 support may hide Java 8+ stream APIs from users.

🏗️Architecture

💡Concepts to learn

  • NIO Selector Pattern (Reactor Pattern) — AndroidAsync's entire architecture revolves around java.nio.channels.Selector—understanding how the event loop multiplexes thousands of sockets without threads is essential to avoiding the library's threading gotchas
  • Non-Blocking Handshakes (TLS/SSL) — Unlike traditional socket libraries where SSL negotiation blocks, AsyncSSLSocketWrapper performs crypto operations asynchronously; understanding the state machine is key for debugging HTTPS issues
  • WebSocket Protocol (RFC 6455) — AndroidAsync includes a WebSocket client/server implementation; knowledge of frame parsing, ping/pong keepalive, and the upgrade handshake is needed to use bidirectional communication features
  • Callback Inversion & Continuations — The library is entirely callback-driven (pre-async/await era); code readability suffers from callback nesting unless you use the Kotlin coroutine wrappers or layer RxJava on top
  • Android Target/Min SDK Versioning — minSdkVersion 14 (Android 4.0) vs compileSdkVersion 29 creates API availability gaps—e.g., TLS 1.2 was backported slowly, affecting HTTPS security in older builds
  • koush/ion — Higher-level HTTP client built directly on top of AndroidAsync—the recommended choice for typical Android apps needing HTTP functionality
  • square/okhttp — Alternative modern HTTP client for Android with thread-pool concurrency model instead of NIO; easier to use but less control over low-level networking
  • square/okio — Companion I/O library providing efficient buffering and encoding—often used together with async networking for data transformation
  • ReactiveX/RxJava — Reactive streams abstraction that wraps async callbacks; many AndroidAsync users layer RxJava for composition and backpressure handling
  • netty/netty — Industry-standard JVM async I/O framework using similar NIO patterns; AndroidAsync is the Android-specialized lightweight variant

🪄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 AsyncSSLSocket and AsyncSSLServerSocket

The repo has SSL socket implementations (AsyncSSLSocket.java, AsyncSSLServerSocket.java, AsyncSSLSocketWrapper.java) but no visible test files for SSL functionality. Given that SSL/TLS is critical for security-sensitive operations like HTTPS, this is a high-value area lacking test coverage. Tests should verify certificate validation, handshake flows, and error handling.

  • [ ] Create AndroidAsync/src/test/java/com/koushikdutta/async/AsyncSSLSocketTest.java with tests for SSL client connections
  • [ ] Create AndroidAsync/src/test/java/com/koushikdutta/async/AsyncSSLServerSocketTest.java with tests for SSL server socket binding and client acceptance
  • [ ] Add test certificates/keys to support SSL tests (self-signed certs in test resources)
  • [ ] Test SSL handshake failures, cipher suite negotiation, and certificate chain validation
  • [ ] Add androidTest instrumentation tests in AndroidAsync-Kotlin for real device SSL scenarios

Add HTTP/WebSocket protocol tests for edge cases and RFC compliance

The repo contains HTTP and WebSocket implementations but the file structure shows minimal test coverage for protocol-level behavior. Key areas like chunked transfer encoding, connection upgrades, frame parsing, and header validation should have explicit tests covering RFC specifications and edge cases.

  • [ ] Create AndroidAsync/src/test/java/com/koushikdutta/async/http/AsyncHttpServerTest.java testing HTTP request/response parsing, headers, and status codes
  • [ ] Create AndroidAsync/src/test/java/com/koushikdutta/async/websocket/WebSocketTest.java for frame parsing, ping/pong, and connection closure
  • [ ] Add tests for malformed requests, oversized payloads, and timeout scenarios
  • [ ] Test HTTP chunked transfer encoding with various chunk sizes
  • [ ] Add integration tests in androidTest directory for end-to-end HTTP and WebSocket flows

Add GitHub Actions CI workflow for automated testing across SDK versions

The repo has minSdkVersion 14 and targetSdkVersion 29, but there's no visible CI configuration (.github/workflows/). This makes it difficult for contributors to validate changes work across Android API levels. A GitHub Actions workflow would catch regressions and verify compatibility.

  • [ ] Create .github/workflows/android-build.yml with gradle build steps for debug and release builds
  • [ ] Configure matrix testing against Android API levels: 16, 21, 24, 29 (covering minSdk gap and common targets)
  • [ ] Add emulator test steps using reactivecircus/android-emulator-runner action to run instrumentation tests
  • [ ] Include lint checks using Android Lint via gradle
  • [ ] Add separate workflow for Kotlin module compilation and unit tests

🌿Good first issues

  • Add instrumented unit tests for AsyncSSLSocketWrapper.java—currently no visible test coverage for TLS handshake edge cases (certificate validation failure, client auth, session resumption)
  • Document the callback execution model with a diagram showing AsyncServer event loop threading guarantees—the single-threaded guarantee is critical but not explicitly documented in README
  • Implement Kotlin Flow-based wrappers in AndroidAsync-Kotlin for streaming operations (like reading chunked HTTP responses)—currently only FutureExtensions.kt exists with no Flow support

Top contributors

Click to expand
  • @koush — 97 commits
  • [@Koushik Dutta](https://github.com/Koushik Dutta) — 2 commits
  • @KaHa6uc — 1 commits

📝Recent commits

Click to expand
  • 12f9e20 — Merge pull request #712 from KaHa6uc/master (koush)
  • 7cb0120 — Add 401 and method to add more (KaHa6uc)
  • 9c19a27 — update (koush)
  • d0042f7 — fixup static constructor (koush)
  • c4fa8e0 — cruft (koush)
  • fff5910 — update (koush)
  • 84e5170 — Merge branch 'master' of ssh://github.com/koush/AndroidAsync (Koushik Dutta)
  • fa0eec4 — update (Koushik Dutta)
  • b29c67f — publishing (koush)
  • 389e804 — asserts (koush)

🔒Security observations

The AndroidAsync library has significant security concerns primarily stemming from severely outdated dependencies and build configuration. The Kotlin version, Android SDK versions, and testing frameworks are all from 2019 and lack critical security patches. The core network handling code (SSL/TLS, socket operations) lacks visible security documentation and configuration details. The low minSdkVersion (14) further compounds security risks by limiting access to modern Android security features. A comprehensive update of all dependencies, build tools, and minimum SDK version is critical before this library can be considered secure for production use. Additionally, security hardening documentation and best practices for SSL/T

  • High · Outdated Kotlin Version — AndroidAsync-Kotlin/build.gradle (ext.kotlin_version = '1.3.61'). The project uses Kotlin 1.3.61, which is significantly outdated (released in December 2019). This version contains known security vulnerabilities and lacks security patches from newer versions. Fix: Update to the latest stable Kotlin version (currently 1.9+). Review Kotlin security advisories and migrate to a supported version that receives security updates.
  • High · Outdated Android Build Tools — AndroidAsync-Kotlin/build.gradle (compileSdkVersion 29, buildToolsVersion '29.0.2'). The project uses compileSdkVersion 29 and buildToolsVersion 29.0.2, which are severely outdated (from 2019). These versions lack security patches and modern security features available in current Android versions. Fix: Update to at least compileSdkVersion 34+ and latest buildToolsVersion. Target SDK should also be updated to match or exceed API level 34.
  • High · Outdated Testing Dependencies — AndroidAsync-Kotlin/build.gradle (androidTestImplementation dependencies). Testing dependencies are severely outdated: androidx.test:runner:1.2.0 and espresso-core:3.2.0 (from 2019) contain known vulnerabilities and lack security patches. Fix: Update androidx.test:runner to 1.6.1+ and espresso-core to 3.5.1+. Review all test dependencies for security updates.
  • Medium · Potential Network Security Misconfiguration — AndroidAsync/src/com/koushikdutta/async/AsyncSSL* files. As a network library handling HTTP/HTTPS and WebSockets, the codebase lacks visible documentation of security hardening measures. SSL/TLS configuration, certificate validation, and cipher suite selection are critical but not visible in the file structure. Fix: Review SSL/TLS implementation to ensure: 1) Certificate pinning where applicable, 2) Strong cipher suites configured, 3) TLS 1.2+ enforced, 4) Hostname verification implemented, 5) Security documentation provided.
  • Medium · Missing Security Configuration Documentation — AndroidAsync/lint.xml, AndroidAsync-Kotlin/proguard-rules.pro. No lint.xml or proguard-rules.pro details visible indicating security-related obfuscation rules, or documented security best practices for developers using this library. Fix: Add clear security guidelines in documentation. Implement proguard rules to protect sensitive code. Enable lint security checks in lint.xml.
  • Medium · Low minSdkVersion — AndroidAsync-Kotlin/build.gradle (minSdkVersion 14). The project targets minSdkVersion 14 (Android 4.0 ICS from 2011), which is extremely outdated and lacks modern security features like stronger cryptography, modern TLS support, and other security APIs. Fix: Increase minSdkVersion to at least 21 (Android 5.0) or higher. This enables access to modern security APIs like TLS 1.2+, stronger cryptographic functions, and other security improvements.
  • Low · Conditional Maven Upload Configuration — AndroidAsync-Kotlin/build.gradle (if condition before maven.gradle). The build.gradle contains conditional code to upload to Maven based on an environment variable check (System.getenv().I_AM_KOUSH == 'true'). This approach could be clearer but is not a security issue by itself. Fix: Consider using Gradle properties or a more explicit configuration management system instead of relying on environment variables for build-time decisions.

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.

Mixed signals · koush/AndroidAsync — RepoPilot