Skip to main content

Overview

Encore.placement(id).show() is a suspend function that returns a PresentationResult. You can either branch on it at the call site (async-result) or register global onPurchaseRequest / onPassthrough handlers (handler-based). Both work; pick whichever fits the call site. For the cross-platform decision tree, see Integration Patterns.

Async-result pattern

Use this when the place you call show() from already has access to your purchase + decline logic.

Basic example

From Compose

onClick is synchronous, so launch a coroutine on the lifecycle scope:

Result type

See PresentationResult.

Handler pattern

Use this when the show() call site is a third-party delegate or a UI action that doesn’t have direct access to your purchase code.

Register in Application.onCreate()

Then show() from anywhere

The handlers fire when the placement resolves. Code at the call site doesn’t need to inspect the returned result.

When to use which

  • Async-result — call site already imports your billing client. Branch-specific code lives at the call site.
  • Handler — Encore is invoked from third-party paywall delegates or from many UI sites that share post-purchase logic.
  • Mixed — handlers handle cross-cutting analytics; specific call sites still branch on show().
See the decision tree for the full rationale.

Re-registration semantics

Each setter replaces the previous lambda. No double-fires.

Platform-specific notes

  • show() is suspend — call from a coroutine scope (lifecycleScope, viewModelScope, rememberCoroutineScope()). The no-arg overload auto-resolves the current foreground Activity; the explicit show(activity: Activity) overload is also available if you need to bind to a specific Activity.
  • Fire-and-forget overloadEncore.placement(id).show(scope) exists if you don’t want to await the result. Equivalent to launching with the handler pattern.
  • PresentationResult.Completed carries offerId and campaignId — the entitlement claim is applied by the SDK; the result fields are for your own analytics.
  • Dismissed vs NoOffersNoOffers fires when the API returns zero offers for this user; Dismissed(DismissReason.USER_CLOSED) fires when the user closes a sheet that did have offers. Dismissed(DismissReason.ERROR) covers presentation failures (e.g., no foreground Activity).
  • JVM target — the SDK is built with JVM target 17. Your app must match (most modern Android Gradle plugins default to this).

See also