π Reconnection System
March 29, 2026 Β· View on GitHub
β Back to README
Everything about how Android DEX detects, handles, and recovers from connection loss β in one place. Phases, triggers, failure states, UI behaviour, and the overlay system.
Overview
Once the boot sequence completes successfully, ReconnectionManager takes over as the connection watchdog. It monitors both the Logic Engine (JAR) and Feature Hub (APK) connections independently, and executes a two-phase recovery strategy when either drops.
Boot Complete
β
βΌ
ReconnectionManager.startMonitoring()
β
βΌ (Listens to ValueNotifier<bool>)
AndroidCore.jarConnected βββ
AndroidCore.apkConnected βββ΄βββΊ _onConnectionChanged()
β
βββββββββββββΌβββββββββββββ
β Is _busy? β skip β
β Both connected? β idle β
βββββββββββββ¬ββββββββββββ-β
β
βΌ
Begin Recovery
Recovery Phases
Phase 1 β Quick Reconnect
Triggered: Immediately on first disconnection detected
Goal: Re-establish the ADB link and restore TCP/WebSocket connections without re-deploying anything
Quick Reconnect
β
ββ adb connect [device ip or -d]
ββ adb reverse tcp:PORT tcp:PORT (all ports)
ββ Wait for JAR to reconnect (if jarReconnecting)
ββ Wait for APK to reconnect (if apkReconnecting)
β
ββ Both reconnected? β phase: idle (success) β
ββ Failed? β proceed to Phase 2
User Message: "Attempting to reconnect to deviceβ¦"
UI: Reconnecting overlay shown; desktop apps frozen
Phase 2 β Full Restart (up to 2 attempts)
Triggered: Quick reconnect failed
Goal: Re-deploy the Logic Engine and re-launch the companion APK service from scratch
Full Restart (attempt 1 of 2)
β
ββ stopJar() ββ kill existing process
ββ killJar() ββ kill Android-side JAR
ββ pushJar() ββ re-upload service module
ββ startJarRuntime() ββ re-launch process
ββ startServerService() ββ re-trigger APK service
ββ Wait for jar.hello + apk.hello
β
ββ Success? β phase: idle β
ββ Failed? β Full Restart (attempt 2 of 2)
β
ββ Success? β phase: idle β
ββ Failed? β phase: FAILED β
User Message: "Performing full restart (attempt N of 2)β¦"
Phase: Failed
Triggered: Both full restart attempts failed
Result: Reconnection overlay shows a permanent error state
User Messages:
- Disconnection (clean):
"Device disconnected. Check your USB cable or Wi-Fi connection." - Unexpected error:
"Reconnection failed unexpectedly. Try restarting the application."
State Model
enum ReconnectionPhase {
idle, // Connected β no action needed
quickReconnect, // Phase 1 in progress
fullRestart, // Phase 2 in progress
failed, // All recovery attempts exhausted
}
class ReconnectionStatus {
final ReconnectionPhase phase;
final bool jarReconnecting; // JAR component specifically recovering
final bool apkReconnecting; // APK component specifically recovering
final String message; // Current user-facing status message
final int attempt; // Current attempt number (1 or 2 in Phase 2)
}
The UI observes ReconnectionManager.instance.status (a ValueNotifier<ReconnectionStatus>) and updates the overlay in real-time.
Partial Disconnection
The system handles partial disconnections β where only one component drops:
| Scenario | jarReconnecting | apkReconnecting | Recovery Action |
|---|---|---|---|
| JAR drops, APK fine | true | false | Only JAR-related steps run |
| APK drops, JAR fine | false | true | Only APK-related steps run |
| Both drop | true | true | Full recovery for both |
Reconnecting Overlay
ReconnectingOverlay is a full-screen widget that appears over the desktop UI during recovery.
What it shows
- Phase indicator β which phase is running
- Component status β JAR and APK individual status pills
- π‘ Reconnecting...
- π΄ Failed
- π’ Connected
- Attempt counter β "Attempt 1 of 2" during full restart
- User message β plain-English status
- Final error state β when
phase == failed, shows the disconnect reason
What it prevents
The overlay blocks all user interaction with the desktop until either:
- Recovery succeeds β overlay dismisses automatically
- Recovery fails β overlay stays up with the error message
Monitoring Lifecycle
| Event | What ReconnectionManager does |
|---|---|
startMonitoring() called | Registers listeners on jarConnected + apkConnected notifiers |
| Connection drops | Triggers _onConnectionChanged() β starts recovery if not _busy |
| Recovery succeeds | Sets phase = idle, clears _busy |
| Recovery fails | Sets phase = failed, clears _busy |
| App restart | startMonitoring() called again after next successful boot |
Note:
startMonitoring()is idempotent β calling it when already monitoring is a no-op.
β Back to README Β· Modules Β» Β· Data Model Β»