Documentation

$appContext

The Android Context, available anywhere — including the places LocalContext.current cannot reach.

The problem it solves

Half of the Android API wants a Context. In Compose you get one from LocalContext.current, but that only works inside a composable — so the moment state logic moves into a store or a ViewModel, the usual answer is to thread a Context through every call, or to keep a static one and hope nothing leaks.

$appContext resolves in all of them:

$onMount {
  Session.load($appContext)
}

It is backed by a generated WhitehallApp : Application registered in the manifest, so it is alive for as long as the process is and cannot outlive anything.

It is the application context

This matters more than it sounds. An application context has no window, which rules out two things:

  • Starting an activity needs a flag. Without a task to launch into, Android requires FLAG_ACTIVITY_NEW_TASK.
  • UI-scoped things will not work. Dialogs and anything else that needs to attach to a window need an activity context, not this one.
$appContext is an escape hatch, not the way to open a link or ask for a permission, even though both need a Context somewhere underneath. Use $open for the first and $permission for the second. Reach for $appContext only when the code asking for a Context is not Whitehall's, such as a library's own initializer.
fun initAnalytics() {
  Analytics.init($appContext, apiKey = $env.PUBLIC_ANALYTICS_KEY)
}

Not for links or sharing

Opening a link and sharing text need a Context too, and both have their own calls. See $open and $share.

What it is good for

UseExample
Storage paths$appContext.filesDir, cacheDir
Preferences and databasesgetSharedPreferences, Room builders
Resources$appContext.resources, assets
System servicesgetSystemService(…)
Launching into a new taskCustom tabs, share sheets, external intents

In a store

Stores are where context-hungry code usually ends up, and they are exactly where LocalContext is unavailable:

@store object Session {
  var token: String? = null

  fun restore() {
    token = $appContext
      .getSharedPreferences("session", Context.MODE_PRIVATE)
      .getString("token", null)
  }
}

See Also