-
Notifications
You must be signed in to change notification settings - Fork 370
Fix StrictMode DiskReadViolations during SDK initialization #871
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This commit addresses three DiskReadViolations that occur when the SDK is initialized on the main thread with StrictMode enabled: 1. PersistentIdentity.getTimeEvents() - Avoid blocking Future.get() on main thread - Added main thread detection using Looper.getMainLooper() - Returns empty map immediately on main thread and loads cache asynchronously - Maintains backward compatibility while preventing disk I/O blocking 2. MPDbAdapter initialization - Defer getDatabasePath() call - Changed database file initialization to use lazy loading pattern - Database path is now resolved only when first accessed - Prevents disk I/O during constructor execution 3. MixpanelAPI constructor - Remove synchronous database file check - Moved first launch detection to background thread - Added checkFirstLaunchAsync() method for async processing - Ensures first open event tracking without blocking main thread Added comprehensive StrictModeTest to verify all violations are resolved while maintaining SDK functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR addresses StrictMode DiskReadViolations that occur during Mixpanel SDK initialization on the main thread. The fix ensures SDK compliance with strict StrictMode policies by deferring disk I/O operations to background threads or using lazy initialization patterns.
Key changes:
- Moved first launch detection and tracking to a background thread to avoid synchronous disk operations during initialization
- Implemented lazy initialization for database file path resolution to defer disk access until actually needed
- Added comprehensive StrictMode compliance testing to verify no violations occur during SDK initialization
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| MixpanelAPI.java | Moved first launch check to background thread via new checkFirstLaunchAsync() method |
| MPDbAdapter.java | Implemented lazy initialization pattern for database file path using synchronized getDatabaseFile() method |
| StrictModeTest.java | Added new instrumented test to verify StrictMode compliance during SDK initialization |
| }); | ||
|
|
||
| // Wait for test to complete | ||
| assertTrue("Test should complete within timeout", |
Copilot
AI
Aug 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The assertTrue method is defined at the bottom of the test class but shadows the static Assert.assertTrue method. This creates confusion and could lead to incorrect test behavior. Use the imported Assert.assertTrue directly or rename the custom method to avoid shadowing.
| }); | ||
|
|
||
| assertTrue("Initialization should complete", | ||
| latch.await(5, TimeUnit.SECONDS)); |
Copilot
AI
Aug 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same issue as line 111 - this assertTrue call uses the custom method instead of the imported Assert.assertTrue, which could lead to inconsistent test behavior.
| latch.await(5, TimeUnit.SECONDS)); | |
| latch.await(5, TimeUnit.SECONDS)); |
- Replace direct Thread creation with SDK's message passing architecture - Add CHECK_FIRST_LAUNCH message type to AnalyticsMessages - Implement FirstLaunchDescription class for message data - Add package-private methods in MixpanelAPI for first launch operations - Update Worker handler to process first launch checks on background thread This follows the SDK's established pattern of using a single HandlerThread for all background operations, avoiding direct thread creation.
Addressed GitHub Copilot FeedbackRefactored the first launch check to use the established message passing pattern instead of creating a new Thread: Changes made:
This approach maintains the SDK's single HandlerThread architecture for all background operations, ensuring consistency and avoiding the overhead of creating additional threads. The StrictMode tests continue to pass, confirming that the disk I/O violations are still resolved while properly following the SDK's architectural patterns. |
The async first launch check was causing timing issues in tests. Implemented a hybrid approach that: - Uses async message passing on main thread to avoid StrictMode violations - Executes synchronously on background threads (like in tests) for reliability This ensures both StrictMode compliance and test stability.
Problem
SDK users are experiencing StrictMode DiskReadViolations when initializing the Mixpanel SDK on the main thread. These violations occur at three specific points during initialization, causing issues for apps that enforce strict StrictMode policies.
Solution
This PR addresses all three DiskReadViolation sources by deferring disk I/O operations to background threads or using lazy initialization patterns:
1. PersistentIdentity.getTimeEvents() violation
Future.get()when loading SharedPreferences on main thread2. MPDbAdapter initialization violation
getDatabasePath()called synchronously in constructor3. MixpanelAPI constructor violation
checkFirstLaunchAsync()methodTesting
StrictModeTestthat verifies no violations occur during SDK initializationImpact
GitHub Copilot Summary
This pull request addresses StrictMode disk I/O violations by ensuring that Mixpanel's initialization and first-launch checks avoid disk reads on the main thread. The changes introduce lazy initialization for database file access, move first-launch tracking to a background thread, and add instrumentation tests to verify compliance with StrictMode policies.
StrictMode compliance and testing:
StrictModeTestto verify that initializingMixpanelAPIon the main thread does not trigger StrictMode disk read violations, and to ensure SDK initialization completes successfully.Database file access improvements:
MPDbAdapter.MPDatabaseHelperto lazily initialize themDatabaseFilefield using a newgetDatabaseFile()method, deferring disk I/O until actually needed. Updated all usages to call this method instead of directly accessing the field. [1] [2] [3] [4]First-launch logic refactor:
$app_openandFIRST_OPEN) into a new asynchronous methodcheckFirstLaunchAsync(), which runs on a background thread to avoid main-thread disk I/O. The synchronous check was removed from the constructor. [1] [2]