Preload Plan¶
Preload plans in advance and reuse them later without the internet during the app lifecycle.
Overview¶
- Use
ExpoFpPlan.preloaderto preload plans. - A preloaded plan is represented by
ExpoFpPreloadedPlanInfo. - You can obtain a presenter for a preloaded plan with
getPreloadedPlanPresenter(...). - Recommended: Preload plans if you expect to reuse them multiple times in one session.
- If a preloaded plan is reloaded with a new
planLink, the link info is automatically updated in the storedExpoFpPreloadedPlanInfo.
Lifecycle Management¶
Important: Preloaded plans are NOT automatically disposed when the Activity/Fragment is destroyed. This allows you to reuse the same presenter across multiple screens without reloading.
- Preloaded plans persist in memory until you explicitly call
disposePreloadedPlan()orremoveAllPreloadedPlans().- You can safely attach and detach the same preloaded presenter to different Activities/Fragments.
- All event callbacks will continue to work after reattaching a preloaded plan.
- You are responsible for disposing preloaded plans when they are no longer needed to free memory.
Step 1. Preload from the Internet¶
Coroutine version (recommended)¶
val expoKey = "YourExpoKey"
val preloadedPlanInfo = ExpoFpPlan.preloader.preloadPlan(
planLink = ExpoFpLinkType.ExpoKey(expoKey)
)
With additional parameters¶
val additionalParams = listOf(ExpoFpPlanParameter.NoOverlay(true), ExpoFpPlanParameter.HideHeaderLogo(true))
val locationProvider: IExpoFpLocationProvider = YourLocationProvider()
val messageListener: IExpoFpPlanMessageListener = YourMessageListener()
val preloadedPlanInfo = ExpoFpPlan.preloader.preloadPlan(
planLink = ExpoFpLinkType.ExpoKey("YourExpoKey"),
additionalParams = additionalParams,
locationProvider = locationProvider,
messageListener = messageListener
)
Step 2. Preload from Downloaded Plan¶
Coroutine version (recommended)¶
val preloadedPlanInfo = ExpoFpPlan.preloader.preloadPlan(
planLink = ExpoFpLinkType.DownloadedPlanInfo(downloadedPlanInfo)
)
With additional parameters¶
val additionalParams = listOf(ExpoFpPlanParameter.NoOverlay(true), ExpoFpPlanParameter.HideHeaderLogo(true))
val locationProvider: IExpoFpLocationProvider = YourLocationProvider()
val messageListener: IExpoFpPlanMessageListener = YourMessageListener()
val preloadedPlanInfo = ExpoFpPlan.preloader.preloadPlan(
planLink = ExpoFpLinkType.DownloadedPlanInfo(downloadedPlanInfo),
additionalParams = additionalParams,
locationProvider = locationProvider,
messageListener = messageListener
)
Step 3. Manage Preloaded Plans¶
Get all preloaded plans:
val preloadedPlansInfo: List<ExpoFpPreloadedPlanInfo> =
ExpoFpPlan.preloader.getPreloadedPlansInfo()
Get a presenter from a preloaded plan:
val presenter = ExpoFpPlan.preloader.getPreloadedPlanPresenter(preloadedPlanInfo)
If only one plan is preloaded, you can get it without parameters:
val presenter = ExpoFpPlan.preloader.getPreloadedPlanPresenter()
Step 4. Show Preloaded Plan¶
View-based UI¶
val planView = presenter.getView()
// IMPORTANT: If reusing a preloaded plan, remove from old parent first
(planView.parent as? ViewGroup)?.removeView(planView)
container.addView(planView)
Note: When reusing a preloaded plan across multiple screens, always remove the view from its old parent before adding it to a new container. Otherwise, you'll get an
IllegalStateException: The specified child already has a parent.
Jetpack Compose¶
AndroidView(
factory = {
presenter.getView().apply {
// Remove from old parent if reusing
(parent as? ViewGroup)?.removeView(this)
}
}
)
Step 5. Delete Preloaded Plans¶
Delete a specific plan:
val presenter = ExpoFpPlan.preloader.disposePreloadedPlan(preloadedPlanInfo)
Delete all plans:
ExpoFpPlan.preloader.removeAllPreloadedPlans()
Best Practices¶
- Preload early: Preload plans during app initialization or screen preparation if you expect repeated access.
- Reuse presenters: Get presenters from preloaded plans instead of creating new ones to reduce loading time.
- Clear when not needed: Dispose preloaded plans when they are no longer needed to free memory.
- Combine with download: Download plans to disk first, then preload them for faster reuse.
Memory Management¶
Preloaded plans remain in memory until explicitly disposed:
class MainActivity : AppCompatActivity() {
private var preloadedPlanInfo: ExpoFpPreloadedPlanInfo? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Preload plan once
if (preloadedPlanInfo == null) {
preloadedPlanInfo = ExpoFpPlan.preloader.preloadPlan(
planLink = ExpoFpLinkType.ExpoKey("demo")
)
}
// Get presenter from preloaded plan
val presenter = ExpoFpPlan.preloader.getPreloadedPlanPresenter(preloadedPlanInfo)
// Attach to view - can be done multiple times across different Activities
presenter?.let {
val planView = it.getView()
container.addView(planView)
}
}
override fun onDestroy() {
super.onDestroy()
// Only dispose when you no longer need the plan
if (isFinishing) {
preloadedPlanInfo?.let {
ExpoFpPlan.preloader.disposePreloadedPlan(it)
}
}
}
}
Reusing Across Multiple Screens¶
Preloaded plans can be safely reused across different Activities or Fragments:
// Activity A
class MapActivityA : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val presenter = ExpoFpPlan.preloader.getPreloadedPlanPresenter(preloadedPlanInfo)
// Get the view from presenter
val planView = presenter?.getView()
// IMPORTANT: Remove from old parent if it was attached before
(planView?.parent as? ViewGroup)?.removeView(planView)
// Now add to this activity's container
container.addView(planView)
// Set message listener for this screen
presenter?.setMessageListener(myListener)
}
// Activity A is destroyed, but plan stays in memory
}
// Activity B - reuse the same preloaded plan
class MapActivityB : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Get the same presenter - no reloading needed!
val presenter = ExpoFpPlan.preloader.getPreloadedPlanPresenter(preloadedPlanInfo)
// Get the view from presenter
val planView = presenter?.getView()
// IMPORTANT: Remove from old parent (Activity A's container) before adding here
(planView?.parent as? ViewGroup)?.removeView(planView)
// Now add to this activity's container
container.addView(planView)
// All callbacks still work
presenter?.setMessageListener(myListener)
}
}