Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ package com.google.maps.android.compose
import android.content.Context
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Text
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ class AdvancedMarkersActivity : ComponentActivity(), OnMapsSdkInitializedCallbac
@SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
MapsInitializer.initialize(applicationContext, MapsInitializer.Renderer.LATEST, this)
enableEdgeToEdge()
setContent {
// Observing and controlling the camera's state can be done with a CameraPositionState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package com.google.maps.android.compose.internal

import android.content.Context
import android.util.Log
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
import com.google.android.gms.common.ConnectionResult
Expand Down Expand Up @@ -80,20 +81,27 @@ public object GoogleMapsInitializer {
public var attributionId: String = AttributionId.VALUE

/**
* Initializes the Google Maps SDK.
* Initializes Google Maps. This function must be called before using any other
* functions in this library.
*
* This function starts the initialization process on a background thread. The process is
* performed only once. If the initialization is already in progress or has completed,
* this function does nothing.
*
* The initialization state can be observed via the `state` property.
* If initialization fails with a recoverable error, the state will be reset
* to [InitializationState.UNINITIALIZED], allowing for a subsequent retry.
* In the case of an unrecoverable error, such as a missing manifest value,
* the state will be set to [InitializationState.FAILURE].
*
* @param context The context to use for initialization.
* @param forceInitialization When true, initialization will be attempted even if it
* has already succeeded or is in progress. This can be useful for retrying a
* failed initialization.
*/
public suspend fun initialize(context: Context) {
public suspend fun initialize(
context: Context,
forceInitialization: Boolean = false,
) {
// 1. Quick exit if already initialized or in progress.
if (_state.value != InitializationState.UNINITIALIZED) {
return
if (!forceInitialization &&
(_state.value == InitializationState.INITIALIZING || _state.value == InitializationState.SUCCESS)) {
return // Already initialized or initializing, and not forced.
}

// 2. Acquire the mutex, perform a double-check (in case another
Expand All @@ -114,24 +122,33 @@ public object GoogleMapsInitializer {
// If the calling scope is cancelled while waiting, withContext will throw
// a CancellationException, and the state will remain INITIALIZING
// (which the catch block will update to FAILURE).
try {
_state.value = try {
withContext(Dispatchers.IO) {
// This is the blocking call. The thread will be blocked here.
// If cancellation happens, the thread STILL finishes this call,
// but the coroutine will immediately throw CancellationException
// *after* this call returns, skipping the state assignments below.
if (MapsInitializer.initialize(context) == ConnectionResult.SUCCESS) {
MapsApiSettings.addInternalUsageAttributionId(context, attributionId)
_state.value = InitializationState.SUCCESS
InitializationState.SUCCESS
} else {
// Handle cases where initialize() returns a non-SUCCESS code
_state.value = InitializationState.FAILURE
InitializationState.FAILURE
}
}
} catch (e: Exception) {
Comment thread
dkhawk marked this conversation as resolved.
when (e) {
is com.google.android.gms.common.GooglePlayServicesMissingManifestValueException -> {
// This is an unrecoverable error.
Log.w("GoogleMapsInitializer", "Initialization failed: missing Google Play Services", e)
Comment thread
dkhawk marked this conversation as resolved.
Outdated
InitializationState.FAILURE
}
else -> {
InitializationState.UNINITIALIZED
}
}
} catch (_: Exception) {
// This will catch any exceptions from the init process (like from mocks in tests)
// Note: By default, this does NOT catch CancellationException.
_state.value = InitializationState.FAILURE
}
}

Expand Down