< Back to all hacks

#39 PocketClaw Launcher APK (8.5 KB)

Launcher
Problem
KISS Launcher uses 33 MB RAM for an unused search bar on a headless phone.
Solution
8.5 KB APK: HOME intent, fullscreen WebView to localhost:9000/dashboard. Built without Android Studio.
Lesson
You don't need Android Studio, Gradle, or any IDE to build an APK. javac + d8 + aapt + apksigner is enough.

Context

Every Android device needs a HOME launcher — the app that shows when you press the Home button. The Moto E2 was using KISS Launcher, a lightweight option at 33 MB RSS. But on a 1 GB device running a Node.js gateway, 33 MB for a search bar that's never used is unacceptable.

The first PocketClaw launcher was a WebView pointed at the local dashboard. WebView loads Chromium's rendering engine, but since we need to display the dashboard anyway, the approach made sense initially. The entire APK was built from the command line without Android Studio, Gradle, or any IDE — just JDK tools and the Android SDK build tools.

This launcher was later replaced by a native version (Hack #40) when WebView's 216 MB RSS proved too expensive.

Implementation

The build chain uses only command-line tools:

# 1. Compile Java source
javac -source 1.7 -target 1.7 -bootclasspath $ANDROID_HOME/platforms/android-23/android.jar \
  -d build/classes LauncherActivity.java

# 2. Convert to DEX (Android bytecode)
d8 --min-api 23 --output build/ build/classes/com/pocketclaw/launcher/LauncherActivity.class

# 3. Package resources + manifest
aapt package -f -M AndroidManifest.xml \
  -I $ANDROID_HOME/platforms/android-23/android.jar \
  -F build/unsigned.apk

# 4. Add DEX to APK
cd build && aapt add unsigned.apk classes.dex

# 5. Sign with debug keystore
apksigner sign --ks ~/.android/debug.keystore --ks-pass pass:android build/unsigned.apk

# 6. Install
adb install -r build/unsigned.apk

The AndroidManifest declares HOME intent:

<intent-filter>
  <action android:name="android.intent.action.MAIN" />
  <category android:name="android.intent.category.HOME" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Verification

# Verify APK installed:
adb shell pm list packages | grep pocketclaw
# Expected: package:com.pocketclaw.launcher

# Check APK size:
adb shell stat -c %s /data/app/com.pocketclaw.launcher-1/base.apk
# Expected: ~8500 bytes

# Set as default launcher:
# Press Home -> select PocketClaw -> "Always"

# Check RAM usage:
adb shell dumpsys meminfo com.pocketclaw.launcher | grep "TOTAL"
# Expected: ~33 MB (WebView version), later ~45 MB with native (Hack #40)

Gotchas

  • WebView loads the full Chromium rendering engine — 216 MB RSS. This negated the purpose of replacing KISS Launcher. Led to Hack #40 (native rewrite)
  • -source 1.7 -target 1.7 is required for Android 6 compatibility. Java 8+ features aren't supported on API 23
  • NEVER disable ALL launchers — Android hangs at boot logo without a HOME activity. Always have at least one launcher enabled before disabling another
  • APK v1 had no escape hatches — fullscreen WebView hid ADB auth popups, causing near-brick scenarios (fixed in Hack #41)
  • com.android.defcontainer must be enabled for adb install to work (re-enable if disabled by debloat)

Result

MetricBeforeAfter
LauncherKISS (33 MB)PocketClaw WebView (33 MB base)
APK size~2 MB (KISS)8.5 KB
Home screenSearch barGateway dashboard
Build toolsAndroid Studiojavac + d8 + aapt