Docs

Initialize

Start the SDK once, in Application.onCreate, with a publishable key.

Call initialize in Application.onCreate

App.kt
import android.app.Application
import link.lander.android.Lander

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        Lander.initialize(
            this,
            apiKey = "pk_live_...", // publishable key from Settings > API keys
            enableLogging = BuildConfig.DEBUG,
        )
    }
}
app/src/main/AndroidManifest.xml
<application android:name=".App" ...>
App.java
public class App extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Lander.initialize(this, "pk_live_...");
    }
}

initialize returns immediately and never touches the network or the disk on the calling thread. Loading (or creating) the install ID, the launch report to Lander (POST /v1/sdk/init) and, on first launch, reading the Play Install Referrer all run in the background, so a slow or missing network never delays your first frame.

Application.onCreate is the right place because it runs before any activity, including when Android starts your process for a link. Initializing from an activity also works, but links handed over before initialize are only processed once it runs.

Parameters

@JvmStatic
@JvmOverloads
fun initialize(
    context: Context,
    apiKey: String,
    baseUrl: String = "https://api.golander.link",
    enableLogging: Boolean = false,
)

Prop

Type

Use a publishable key

Create keys in the dashboard under Settings > API keys (Dashboard: API keys). Only publishable keys are accepted:

KeyIn an app?
pk_test_...Yes. Test environment.
pk_live_...Yes. Live environment.
sk_test_..., sk_live_...Never. initialize throws an IllegalArgumentException.

Anything you ship in an APK is public, which is why secret keys are refused outright. Any other value that is not a publishable key (pk_test_ or pk_live_ followed by at least 24 letters or digits) also throws an IllegalArgumentException, right away, from initialize itself. Surrounding whitespace is ignored, and the message never contains the key, so it is safe to log or report to a crash reporter.

Test and live builds

The key you pass decides which environment the app talks to. Links created in the test environment only resolve for apps using a pk_test_ key, and live links only for pk_live_ keys. See Environments.

A simple way to switch is a buildConfigField per build type:

app/build.gradle.kts
android {
    buildFeatures { buildConfig = true }
    buildTypes {
        debug { buildConfigField("String", "LANDER_KEY", "\"pk_test_...\"") }
        release { buildConfigField("String", "LANDER_KEY", "\"pk_live_...\"") }
    }
}
App.kt
Lander.initialize(this, apiKey = BuildConfig.LANDER_KEY, enableLogging = BuildConfig.DEBUG)

If you switch an existing install from a test key to a live key (or to another project), Lander reports that the install ID belongs elsewhere (install_id_conflict). The SDK then creates a fresh install ID and reports a first launch, so nothing breaks.

What initialize does

  1. Validates the key (throws IllegalArgumentException for secret or malformed keys).
  2. Registers activity lifecycle callbacks on your Application, to flush events when the app goes to the background and to know when the first activity is showing.
  3. In the background, loads the install ID from storage, or creates a random UUID v4 on first launch.
  4. Reports the launch with POST /v1/sdk/init. On a first launch it reads the Play Install Referrer (waiting at most 5 seconds) and sends it along, and the answer may carry a deferred link.
  5. Loads any events left in the on device queue from earlier sessions and sends them.

initialize never throws because of the network. A failed launch report is logged (when logging is on). A failed first launch report is retried in the same session (when the app returns to the foreground, before claimHandoff and before events are sent) and on the next launch. The install is counted once, because the API keeps one record per install ID.

Rules worth knowing

  • Call it once. A second call is ignored (it logs a message when logging is on).
  • Other methods need it. getInitialLink, createLink, claimHandoff and trackEvent throw IllegalStateException if you call them before initialize.
  • handleIntent, deepLinks and addDeepLinkListener do not. You can collect Lander.deepLinks and hand over intents before initialize; links wait until the SDK starts.
  • installId is null until it has loaded, a few milliseconds after initialize.
  • Thread safe. Every method can be called from any thread. Suspending functions do their work off the main thread, and Java callbacks arrive on the main thread.

The install ID

Lander.installId is the random UUID v4 the SDK created for this install. It is not tied to the device or the user:

  • It is stored in noBackupFilesDir, which Android never backs up, so it is never restored onto another device.
  • It is gone when the app is uninstalled or its data is cleared. A reinstall gets a new one.

It is handy for support requests: show it in a debug screen so testers can quote it.

installIdText.text = "Install ID: ${Lander.installId ?: "(loading)"}"

Next steps

On this page