-
-
Notifications
You must be signed in to change notification settings - Fork 81
Service Connection
This page documents how Shizuku+ starts its privileged service, how connection errors are handled, and what the background auto-start system does on your behalf.
Tapping Start on the home screen opens the connection terminal. The flow has four phases:
Shizuku+ resolves a port in priority order:
| Priority | Source | Notes |
|---|---|---|
| 1 | System property (adb_tcp_port) |
Set when Wireless Debugging is already active |
| 2 | Loopback probe (127.0.0.1:5555, then last/custom port) |
AdbPortProber opens a fast TCP socket (150 ms timeout) — works with no Wi-Fi, over 5G/LTE, or fully offline |
| 3 | mDNS discovery | Broadcast by the device when Wireless Debugging is on |
| 4 | Last saved port | Remembered from the most recent successful connection |
If none are available, the discovery dialog opens and waits for the system to advertise a port.
Android disables mDNS advertisement on cellular data, which historically made Wireless Debugging look "broken" whenever you weren't on Wi-Fi. Shizuku+ works around this by probing the loopback interface directly:
-
AdbPortProberopens a TCP socket to127.0.0.1on candidate ports (standard5555first, then your last-used and custom TCP ports). If ADB's TCP/IP mode is already listening, the connection is instant — no Wi-Fi and no mDNS required. This enables a 1-tap start on cellular or with the network fully off. - The connection dialog polls loopback live, so it connects the moment port
5555(or a Mobile Hotspot) starts listening. - When mDNS genuinely is the only option, the dialog surfaces a diagnostic banner and a Mobile Hotspot launcher, explaining that enabling the hotspot lets Wireless Debugging work over 5G.
AdbClient connects to 127.0.0.1:<port> using TLS. Up to 8 attempts with exponential back-off (200 ms → 3 s cap) are made before giving up, handling transient readiness delays after the port is advertised.
If TCP Mode is enabled and the active port differs from the stored TCP port, Shizuku+ first connects on the current port and issues tcpip:<stored_port> to switch ADB into persistent TCP mode before the main connection.
Once connected, Shizuku+ runs libshizuku.so --apk=<path> over the ADB shell channel. This starts the privileged shizuku_server process.
After the launch command returns, Shizuku+ waits up to 15 seconds for the server binder to register. If the binder does not arrive in time, it silently retries once (another 15 s window) before surfacing the timeout error dialog.
On success, the elapsed wait time is shown (Connected in 1.3s) and the terminal closes immediately with haptic feedback.
| Element | Behaviour |
|---|---|
| Progress bar | Indeterminate; visible during connection, hidden on error |
| Cancel | Dismisses the terminal immediately at any point |
| Elapsed time |
"Connected in X.Xs" logged just before auto-close |
| Retry | Appears in every error dialog; clears the terminal and restarts from phase 2 |
| Auto-close | Terminal closes the moment the binder is confirmed — no artificial delay |
| Error | Meaning | Recovery |
|---|---|---|
| Can't connect to port | ADB port not reachable — often blocked by a firewall, VPN, or ad-blocker | Whitelist Shizuku+ in any network filtering app |
| Service did not start in time | Server started but binder not received within 30 s total (2 × 15 s) | Check Wireless Debugging is still enabled; tap Retry |
| Please pair first | Device requires pairing before connecting | Go through the pairing flow in Developer Options |
| Unable to generate key | Device KeyStore is broken | May require a factory reset or OEM-specific repair |
| SSL handshake failed | ADB keys are corrupted | Tap "Go to Developer Options" in the dialog and reset ADB keys |
| Root not granted | Root shell is unavailable | Grant root to Shizuku+ in your root manager |
| Unexpected error | Unclassified exception | See the terminal log for details; tap Retry |
For devices that can't use Wireless ADB (older Android, or you'd rather use a computer), Shizuku+ can be started with a one-time adb command run from a PC. This has to be repeated after every device restart — there's no persistent pairing like Wireless ADB has.
-
Install platform-tools on your computer if you don't have
adbalready (Google's official download). - Enable USB debugging: Settings → About phone → tap "Build number" 7 times to unlock Developer Options, then Settings → Developer options → enable USB debugging.
-
Connect your device: plug in via USB (accept the "Allow USB debugging?" prompt on the phone), or use
adb connect <device-ip>:<port>if you've already got the device reachable over Wi-Fi. - Get the exact command for your install: open Shizuku+ → the "Start via ADB" card → View command. The path is specific to your device/install, so copy it from there rather than typing it by hand.
-
Run it in a terminal on your computer:
adb shell <the path you copied>.
If adb devices doesn't show your phone, the USB debugging prompt wasn't accepted, or you're on the wrong USB cable/port (some cables are charge-only). If the command runs but nothing happens in the app, see Error Reference above — the same failure modes apply.
When root is the last-used launch method, Shizuku+ skips ADB entirely:
- Acquires a root shell via
libsu. - Runs
libshizuku.so --apk=<path>as root. - Waits for the binder (same 15 s × 2 logic as the ADB path).
The root path has the same progress indicator, cancel, and retry behaviour as the ADB path.
BootCompleteReceiver fires on BOOT_COMPLETED, LOCKED_BOOT_COMPLETED, MY_PACKAGE_REPLACED, and HTC/Xiaomi quick-boot broadcasts.
It reads the last launch method and dispatches accordingly:
-
ADB: Enqueues
AdbStartWorkervia WorkManager with optional Wi-Fi constraint. -
Root: Runs
ShizukuReceiverStarter.rootStart()directly.
The worker resolves a port using the same priority order as interactive starts, with one addition: the saved last port is tried as a fast-path before launching mDNS discovery. On devices where the port is stable across reboots, this makes background starts significantly faster.
1. System property port → connect immediately
2. Loopback probe → connect immediately (127.0.0.1:5555 / last / custom port)
3. Last saved port → connect immediately (fast-path, no discovery needed)
4. mDNS discovery → wait up to 15 s for the device to advertise a port
Cellular / 5G auto-reconnect: background reconnection previously refused to run whenever Wi-Fi was off, because the worker's Wi-Fi constraint (EnvironmentUtils.isWifiRequired()) was unconditional. It now returns false — i.e. Wi-Fi is not required — when TCP mode is on, when adb_tcp_port is set, or when a loopback probe finds 5555/the last port already listening. So if ADB TCP/IP is active, the service auto-reconnects after a reboot even on cellular data with no Wi-Fi in range.
When enabled in Settings, WatchdogService runs as a foreground service and monitors the ShizukuStateMachine state flow. On a CRASHED state:
- Waits for the exponential back-off cooldown (
5 s → 10 s → 20 s … → 5 min cap). - Calls
ShizukuReceiverStarter.start()to relaunch the service. - Resets the crash counter once the service is confirmed running.
- Shows a crash notification with links to learn more or disable alerts.
Two independent layers exist purely because they fail differently, and each covers a gap the other can't:
| Layer | Interval | What it catches |
|---|---|---|
WatchdogService |
Continuous (state-flow listener) | Fast, in-process recovery from a normal Shizuku crash |
WatchdogWorker (WorkManager) |
Every 2 hours | Restarts WatchdogService if the OS killed just that service but left the app process alive |
WatchdogAlarmReceiver (AlarmManager) |
Every 15 minutes | Restarts everything if the entire app process was killed — the case neither of the above can self-detect, because both run inside the process that got killed |
That third layer exists because some OEM battery managers (most notably Samsung One UI's "Sleeping apps" freezer) don't just kill a service — they freeze or kill the whole process, watchdog included, on screen lock (#415, #417). A dead or frozen process can't notice its own death. AlarmManager alarms are dispatched by the system itself (system_server), so the alarm can cold-start a fresh process to check on Shizuku even if the previous one never got the chance to. This needs the SCHEDULE_EXACT_ALARM permission for tight timing; if you decline it (or your OEM restricts it), Shizuku+ falls back to an inexact wake automatically — see Permissions.
This is a mitigation, not a full fix — if your OEM's freezer is aggressive enough, the app being fully asleep can still delay recovery by up to the alarm interval. If you're on a Samsung device, exempting Shizuku+ from Settings → Battery → Background usage limits → Sleeping apps manually still gives the most reliable result.
Every service start and watchdog restart is logged to the Activity Log (Settings → Activity Log):
| Event | Log entry |
|---|---|
| Interactive ADB start | Service started via ADB on port <N> |
| Interactive root start | Service started via root |
| Background worker start | Service started via background ADB worker on port <N> |
| Watchdog restart | Watchdog: restarting after crash #<N> |
After every successful ADB connection, Shizuku+ saves the port to SharedPreferences (last_adb_port). This port is used as a fallback in three places:
- Interactive start (home screen Start button)
-
AdbStartWorkerbackground start - mDNS discovery dialog (if the saved port is still valid, the dialog resolves immediately)
The saved port is updated on every successful connection, so it always reflects the most recent working configuration.