Skip to content

Race condition in Amplitude initialization causing crash #247

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

Closed
mformetal opened this issue Mar 5, 2025 · 4 comments
Closed

Race condition in Amplitude initialization causing crash #247

mformetal opened this issue Mar 5, 2025 · 4 comments

Comments

@mformetal
Copy link

mformetal commented Mar 5, 2025

Expected Behavior

Calling the Amplitude constructor should not result in a crash.

Current Behavior

The constructor of the .core.Amplitude class has logic for building the rest of the SDK - notably, buildInternal. The .android.Amplitude implementation overrides buildInternal and uses a class-level field:

override suspend fun buildInternal(identityConfiguration: IdentityConfiguration) {
        val migrationManager = MigrationManager(this)
        migrationManager.migrateOldStorage()

        this.createIdentityContainer(identityConfiguration)

        if (this.configuration.offline != AndroidNetworkConnectivityCheckerPlugin.Disabled) {
            add(AndroidNetworkConnectivityCheckerPlugin())
        }
        androidContextPlugin = object : AndroidContextPlugin() {
            override fun setDeviceId(deviceId: String) {
                // call internal method to set deviceId immediately i.e. dont' wait for build() to complete
                [email protected](deviceId)
            }
        }
        add(androidContextPlugin)
        add(GetAmpliExtrasPlugin())
        add(AndroidLifecyclePlugin(activityLifecycleCallbacks)) <--- HERE
        add(AnalyticsConnectorIdentityPlugin())
        add(AnalyticsConnectorPlugin())
        add(AmplitudeDestination())

        (timeline as Timeline).start()
    }

activityLifecycleCallbacks is defined as a val within .android.Amplitude, initialized during class creation. However, since all of this logic is happening in inits (one for the parent .core.Amplitude and one for the child .android.Amplitude), what's seemingly possible is a race to initialize, causing this crash:

  Fatal Exception: java.lang.NullPointerException: Parameter specified as non-null is null: method com.amplitude.android.plugins.AndroidLifecyclePlugin.<init>, parameter activityLifecycleObserver
       at com.amplitude.android.plugins.AndroidLifecyclePlugin.<init>(AndroidLifecyclePlugin.kt:3)
       at com.amplitude.android.Amplitude.buildInternal$suspendImpl(Amplitude.kt:75)
       at com.amplitude.android.Amplitude.buildInternal(Amplitude.kt:1)
       at com.amplitude.core.Amplitude$build$built$1.invokeSuspend(Amplitude.kt:117)
       at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
       at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:101)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:637)
       at java.lang.Thread.run(Thread.java:1012)

Possible Solution

Possible ideas, not sure of feasibility with other clients:

  1. Don't construct things in init, let the caller decide when that logic happens
  2. Pass ActivityLifecycleCallbacks to the constructor of .android.Amplitude so it's already initialized when needed

Steps to Reproduce

  1. Open an app using the Amplitude Kotlin SDK
  2. Initialize it immediately in Application.onCreate
  3. Background the app
  4. Rarely the app will crash

Environment

  • Unity Plugin Version: Amplitude-Android 1.19.4
  • Device: Motorola, Samsung, Oneplus, etc
  • Device OS and Version: Android 9 and above
@izaaz
Copy link
Collaborator

izaaz commented Mar 5, 2025

@mformetal can you please confirm the SDK version that you're using?

@mformetal
Copy link
Author

@mformetal can you please confirm the SDK version that you're using?

So sorry, just updated the issue description

@izaaz
Copy link
Collaborator

izaaz commented Mar 5, 2025

@mformetal can you please try version 1.20.1. I believe this issue was fixed recently

#243

@mformetal
Copy link
Author

@mformetal can you please try version 1.20.1. I believe this issue was fixed recently

#243

Love to see it - we'll give this version a try!

@izaaz izaaz closed this as completed Mar 20, 2025
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

No branches or pull requests

2 participants