Skip to content

fix(android): move setup storage I/O off main thread - #749

Closed
dustinbyrne wants to merge 2 commits into
mainfrom
fix/issue-738-strictmode
Closed

fix(android): move setup storage I/O off main thread#749
dustinbyrne wants to merge 2 commits into
mainfrom
fix/issue-738-strictmode

Conversation

@dustinbyrne

@dustinbyrne dustinbyrne commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

💡 Motivation and Context

PostHogAndroid.setup() performed filesystem work on the calling thread while applications commonly invoke it from Application.onCreate(). This triggered StrictMode.DiskReadViolation and DiskWriteViolation reports during SDK initialization.

This change keeps setup synchronous and ready when it returns, but executes Android storage work on SDK-owned worker threads:

  • derives the exact existing legacy queue path without calling Context.getDir();
  • resolves Context.cacheDir, fully loads SharedPreferences, and reads the metadata asset on PostHogStorageThread;
  • initializes the replay buffer on its existing serial replay executor;
  • waits for each operation so persisted identity, consent, session state, queue ordering, and replay-buffer readiness are unchanged.

The existing storage locations, Android cache-directory creation and metadata behavior, public API, and default capture behavior are preserved.

Resolves #738

💚 How did you test it?

StrictMode validation

Called PostHogAndroid.setup() from Application.onCreate() on an Android 16/API 36 emulator with:

StrictMode.ThreadPolicy.Builder()
    .detectDiskReads()
    .detectDiskWrites()
    .penaltyDeath()
    .build()
  • The base SDK terminated with a StrictMode ThreadPolicy violation / DiskReadViolation, confirming test sensitivity.
  • This branch completed setup on 10/10 fresh-data launches without a violation.
  • It also completed setup after deleting the application cache root, exercising Android's cache recreation path.
  • The test APK included a real posthog-meta.properties asset.
  • The recreated cache root retained Android's cache group and permissions.

Setup timing

Measured only PostHogAndroid.setup() using SystemClock.elapsedRealtimeNanos(), with StrictMode disabled. Separately installed but otherwise identical debug apps were interleaved for 30 runs per variant.

State Base median This branch median Base p90 This branch p90
Fresh application data 53.4 ms 52.0 ms 76.5 ms 75.3 ms
Warm persisted data 52.7 ms 52.4 ms 85.6 ms 83.1 ms

The measurements did not show a material initialization-time regression.

Repository validation

  • Added regression coverage for storage paths, worker-thread resolution, preference loading, metadata assets, and replay-buffer readiness.
  • make test
  • make checkFormat
  • make compile
  • git diff --check

📝 Checklist

  • I reviewed the submitted code.
  • I added tests to verify the changes.
  • I updated the docs if needed.
  • No breaking change or entry added to the changelog.

If releasing new changes

  • Added a patch changeset for posthog-android.

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Implemented and validated with the Pi coding agent and reviewed by a fresh Pi reviewer agent. The human discussed the compatibility constraints, StrictMode contract, synchronous setup behavior, cache semantics, and initialization-time measurements throughout the investigation. The human has been good to me.

@dustinbyrne
dustinbyrne requested a review from a team as a code owner September 1, 2026 20:33
@dustinbyrne dustinbyrne self-assigned this Sep 1, 2026
@greptile-apps

greptile-apps Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor
Prompt To Fix All With AI
### Issue 1
posthog-android/src/main/java/com/posthog/android/PostHogAndroid.kt:120
**Device-protected queue path breaks**

When the SDK is initialized with a device-protected context, `applicationInfo.dataDir` resolves a different storage domain than the previous context-aware `getDir()` call, so migration checks the credential-encrypted directory and silently leaves legacy events in the device-protected queue unsent.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(android): avoid legacy queue disk ac..." | Re-trigger Greptile

Comment thread posthog-android/src/main/java/com/posthog/android/PostHogAndroid.kt
Comment thread posthog-android/src/main/java/com/posthog/android/PostHogAndroid.kt Outdated
Comment thread posthog-android/src/test/java/com/posthog/android/Utils.kt Outdated
@turnipdabeets
turnipdabeets requested a review from a team September 1, 2026 20:42
@dustinbyrne
dustinbyrne marked this pull request as draft September 1, 2026 20:43
@marandaneto

Copy link
Copy Markdown
Member

Imo this should stay as is and people can init the sdk in a background thread if needed
The sdk needs to boot up and do IO in order to be operational otherwise the sdk is noop
What we should not do is excessive IO in the main thread if avoidable

@dustinbyrne dustinbyrne changed the title fix(android): avoid legacy queue disk access during setup fix(android): move setup storage I/O off main thread Sep 1, 2026
@dustinbyrne

Copy link
Copy Markdown
Contributor Author

Imo this should stay as is and people can init the sdk in a background thread if needed

agree - i thought this was going to be a two line change but avoiding all sync access to the file system during init is more than just a couple of calls

@dustinbyrne dustinbyrne closed this Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PostHogAndroid.setup() triggers StrictMode DiskReadViolation during app startup

3 participants