Skip to content

Commit 262ecd1

Browse files
author
markvdouw
authored
feat: lazy initialization of the SDK based on events and Android lifecycle functions triggered (#104)
* Lazy initialization of the SDK based on events and Android lifecycle functions triggered. * Changes due to PR comments
1 parent 1d7bc37 commit 262ecd1

1 file changed

Lines changed: 103 additions & 40 deletions

File tree

src/main/kotlin/com/mparticle/kits/SingularKit.kt

Lines changed: 103 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,13 @@ import com.mparticle.commerce.Product
1414
import com.mparticle.consent.ConsentState
1515
import com.mparticle.internal.Logger
1616
import com.mparticle.internal.MPUtility
17-
import com.mparticle.kits.KitIntegration.*
17+
import com.mparticle.kits.KitIntegration.ActivityListener
18+
import com.mparticle.kits.KitIntegration.ApplicationStateListener
19+
import com.mparticle.kits.KitIntegration.AttributeListener
20+
import com.mparticle.kits.KitIntegration.CommerceListener
21+
import com.mparticle.kits.KitIntegration.EventListener
22+
import com.mparticle.kits.KitIntegration.PushListener
23+
import com.mparticle.kits.KitIntegration.UserAttributeListener
1824
import com.singular.sdk.Singular
1925
import com.singular.sdk.SingularConfig
2026
import com.singular.sdk.internal.SingularLog
@@ -26,6 +32,8 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
2632
PushListener, CommerceListener, ApplicationStateListener, UserAttributeListener,
2733
AttributeListener {
2834
private val logger = SingularLog.getLogger(Singular::class.java.simpleName)
35+
private var isInitialized = false
36+
private var deviceToken: String? = null
2937

3038
//endregion
3139
//region Kit Integration Implementation
@@ -36,16 +44,13 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
3644
// Returning the reporting message to state that the method was successful and
3745
// Preventing from the mParticle Kit to retry to activate to method.
3846
val messages: MutableList<ReportingMessage> = ArrayList()
39-
if (Singular.init(context, buildSingularConfig(settings))) {
40-
singularSettings = settings
41-
messages.add(
42-
ReportingMessage(
43-
this,
44-
ReportingMessage.MessageType.APP_STATE_TRANSITION,
45-
System.currentTimeMillis(), null
46-
)
47+
messages.add(
48+
ReportingMessage(
49+
this,
50+
ReportingMessage.MessageType.APP_STATE_TRANSITION,
51+
System.currentTimeMillis(), null
4752
)
48-
}
53+
)
4954
return messages
5055
}
5156

@@ -120,8 +125,10 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
120125
}
121126

122127
//region Unimplemented (Empty Methods)
123-
override fun onActivityCreated(activity: Activity, bundle: Bundle?): List<ReportingMessage> =
124-
emptyList()
128+
override fun onActivityCreated(activity: Activity, bundle: Bundle?): List<ReportingMessage> {
129+
initializeSingular()
130+
return emptyList()
131+
}
125132

126133
override fun onActivityStarted(activity: Activity): List<ReportingMessage> = emptyList()
127134

@@ -140,21 +147,23 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
140147
//region Event Listener Implementation
141148
override fun logEvent(mpEvent: MPEvent): List<ReportingMessage>? {
142149
val messages: MutableList<ReportingMessage> = ArrayList()
143-
val eventName = mpEvent.eventName
144-
val eventInfo = mpEvent.customAttributes
150+
executeIfSingularInitialized({
151+
val eventName = mpEvent.eventName
152+
val eventInfo = mpEvent.customAttributes
145153

146-
// Logging the event with the Singular API
147-
val eventStatus: Boolean = if (!eventInfo.isNullOrEmpty()) {
148-
Singular.eventJSON(eventName, JSONObject(eventInfo))
149-
} else {
150-
Singular.event(eventName)
151-
}
154+
// Logging the event with the Singular API
155+
val eventStatus: Boolean = if (!eventInfo.isNullOrEmpty()) {
156+
Singular.eventJSON(eventName, JSONObject(eventInfo))
157+
} else {
158+
Singular.event(eventName)
159+
}
152160

153-
// If the Singular event logging was successful, return the message to the mParticle Kit
154-
// So it won't retry the event
155-
if (eventStatus) {
156-
messages.add(ReportingMessage.fromEvent(this, mpEvent))
157-
}
161+
// If the Singular event logging was successful, return the message to the mParticle Kit
162+
// So it won't retry the event
163+
if (eventStatus) {
164+
messages.add(ReportingMessage.fromEvent(this, mpEvent))
165+
}
166+
}, forceInitSingular = true, "logEvent")
158167
return messages
159168
}
160169

@@ -178,12 +187,48 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
178187
//region Push Listener Implementation
179188
override fun onPushRegistration(deviceToken: String, senderId: String): Boolean {
180189
// Saving the registration token to determine when the user uninstalls the app.
181-
if (MPUtility.isFirebaseAvailable()) {
182-
Singular.setFCMDeviceToken(deviceToken)
183-
}
190+
this.deviceToken = deviceToken
191+
executeIfSingularInitialized({
192+
if (MPUtility.isFirebaseAvailable()) {
193+
Singular.setFCMDeviceToken(deviceToken)
194+
}
195+
}, forceInitSingular = false, "onPushRegistration")
184196
return true
185197
}
186198

199+
private fun executeIfSingularInitialized(
200+
operation: () -> Unit,
201+
forceInitSingular: Boolean = false,
202+
operationName: String
203+
) {
204+
if (isInitialized) {
205+
operation.invoke()
206+
Logger.debug("$operationName executed")
207+
} else {
208+
if (forceInitSingular) {
209+
initializeSingular()
210+
executeIfSingularInitialized(operation, false, operationName)
211+
} else {
212+
Logger.debug("$operationName can't be executed, Singular not initialized")
213+
}
214+
}
215+
}
216+
217+
private fun initializeSingular() {
218+
if (!isInitialized) {
219+
if (Singular.init(context, buildSingularConfig(settings))) {
220+
currentUser?.id?.toString()?.let { Singular.setCustomUserId(it) }
221+
isInitialized = true
222+
singularSettings = settings
223+
deviceToken?.let { deviceToken ->
224+
if (MPUtility.isFirebaseAvailable()) {
225+
Singular.setFCMDeviceToken(deviceToken)
226+
}
227+
}
228+
}
229+
}
230+
}
231+
187232
//region Unimplemented (Empty Methods)
188233
override fun willHandlePushMessage(intent: Intent): Boolean = false
189234

@@ -193,11 +238,15 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
193238
//endregion
194239
//region Commerce Listener Implementation
195240
override fun logEvent(commerceEvent: CommerceEvent): List<ReportingMessage> {
196-
return if (commerceEvent.productAction == Product.PURCHASE) {
197-
handlePurchaseEvents(commerceEvent)
198-
} else {
199-
handleNonPurchaseEvents(commerceEvent)
200-
}
241+
var list = emptyList<ReportingMessage>()
242+
executeIfSingularInitialized(operation = {
243+
if (commerceEvent.productAction == Product.PURCHASE) {
244+
list = handlePurchaseEvents(commerceEvent)
245+
} else {
246+
list = handleNonPurchaseEvents(commerceEvent)
247+
}
248+
}, forceInitSingular = true, "logEvent")
249+
return list
201250
}
202251

203252
private fun handlePurchaseEvents(commerceEvent: CommerceEvent): List<ReportingMessage> {
@@ -264,7 +313,11 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
264313
}
265314
}
266315
if (map.isNotEmpty()) {
267-
Singular.eventJSON("UserAttribute", (map as Map<*, *>?)?.let { JSONObject(it) })
316+
executeIfSingularInitialized(
317+
{
318+
Singular.eventJSON("UserAttribute", (map as Map<*, *>?)?.let { JSONObject(it) })
319+
}, forceInitSingular = false, "setUserAttribute"
320+
)
268321
}
269322
}
270323

@@ -312,34 +365,44 @@ open class SingularKit : KitIntegration(), ActivityListener, EventListener,
312365
filteredMParticleUser: FilteredMParticleUser
313366
) {
314367

315-
consentState.ccpaConsentState?.let { Singular.limitDataSharing(it.isConsented) }
368+
executeIfSingularInitialized({
369+
consentState.ccpaConsentState?.let { Singular.limitDataSharing(it.isConsented) }
370+
}, forceInitSingular = false, "onConsentStateUpdated")
316371

317372
}
318373

319374
override fun setAllUserAttributes(map: Map<String, String>, map1: Map<String, List<String>>) {}
320375
override fun removeUserAttribute(s: String) {}
321376
override fun setUserIdentity(identityType: IdentityType, s: String) {
322377
if (identityType == IdentityType.CustomerId) {
323-
Singular.setCustomUserId(s)
378+
executeIfSingularInitialized({
379+
Singular.setCustomUserId(s)
380+
}, forceInitSingular = false, "setUserIdentity")
324381
}
325382
}
326383

327384
override fun removeUserIdentity(identityType: IdentityType) {
328385
if (identityType == IdentityType.CustomerId) {
329-
Singular.unsetCustomUserId()
386+
executeIfSingularInitialized({
387+
Singular.unsetCustomUserId()
388+
isInitialized = false
389+
}, forceInitSingular = false, "removeUserIdentity")
330390
}
331391
}
332392

333393
override fun logout(): List<ReportingMessage> {
334-
Singular.unsetCustomUserId()
335394
val messageList: MutableList<ReportingMessage> = ArrayList()
336-
messageList.add(ReportingMessage.logoutMessage(this))
395+
executeIfSingularInitialized({
396+
Singular.unsetCustomUserId()
397+
isInitialized = false
398+
messageList.add(ReportingMessage.logoutMessage(this))
399+
}, forceInitSingular = false, "logout")
337400
return messageList
338401
}
339402

340403
override fun onApplicationForeground() {
341404
// Handling deeplinks when the application resumes from background
342-
Singular.init(context, buildSingularConfig(singularSettings))
405+
initializeSingular()
343406
}
344407

345408
override fun onApplicationBackground() {} //endregion

0 commit comments

Comments
 (0)