Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[analytics] Option to Deinit / dispose SRGAnalytics #889

Open
2 tasks done
Gustl22 opened this issue Feb 11, 2025 · 6 comments
Open
2 tasks done

[analytics] Option to Deinit / dispose SRGAnalytics #889

Gustl22 opened this issue Feb 11, 2025 · 6 comments
Labels
enhancement New feature or request

Comments

@Gustl22
Copy link

Gustl22 commented Feb 11, 2025

Is there an existing similar feature request?

  • I have searched existing features and found no similar request.

  • I have browsed the available API and found no way to achieve the use case I described.

Use case description

If initializing Analytics twice with SRGAnalytics.init(applicationContext, config), it gives the following error message:

java.lang.IllegalArgumentException: Already initialized
	at ch.srgssr.pillarbox.analytics.SRGAnalytics.init(SRGAnalytics.kt:95)
	at ch.srgssr.srg_analytics.flutter.SrgAnalyticsPlugin.initialize(SrgAnalyticsPlugin.kt:53)
	at ch.srgssr.srg_analytics.flutter.SrgAnalyticsApi$Companion.setUp$lambda$2$lambda$1(Messages.kt:214)
	at ch.srgssr.srg_analytics.flutter.SrgAnalyticsApi$Companion.$r8$lambda$mTsXPo0EiHDJNp9MvI45M2XGxuo(Messages.kt:0)
	at ch.srgssr.srg_analytics.flutter.SrgAnalyticsApi$Companion$$ExternalSyntheticLambda1.onMessage(R8$$SyntheticClass:0)
	at io.flutter.plugin.common.BasicMessageChannel$IncomingMessageHandler.onMessage(BasicMessageChannel.java:261)
	at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
	at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0(DartMessenger.java:319)
	at io.flutter.embedding.engine.dart.DartMessenger.$r8$lambda$BqGJF3aBeRT05gDeKMoHH6eOjH0(DartMessenger.java:0)
	at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(R8$$SyntheticClass:0)
	at android.os.Handler.handleCallback(Handler.java:959)
	at android.os.Handler.dispatchMessage(Handler.java:100)
	at android.os.Looper.loopOnce(Looper.java:232)
	at android.os.Looper.loop(Looper.java:317)
	at android.app.ActivityThread.main(ActivityThread.java:8705)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
, null)

To prevent that, we need the possibility to deinit the analyics, e.g. when the app goes in background or is closed, as our app life cycle starts when the app is in the foreground.

Acceptance criteria

Ability to properly deinit the SRGAnalytics

Proposed solution

Add a dispose or deinit method.

Alternatives considered

Allow to initialize SRG Analytics more than once (?)

@Gustl22 Gustl22 added enhancement New feature or request triage Requires triage first labels Feb 11, 2025
@github-project-automation github-project-automation bot moved this to ✏️ Draft in Pillarbox Feb 11, 2025
@StaehliJ
Copy link
Contributor

Where do you init analytics in you project?

Because if you do it like it is recommended inside the Application the init is called only once. There is no needs to deinit SRGAnalytics when in background.

@StaehliJ StaehliJ removed the triage Requires triage first label Feb 12, 2025
@StaehliJ StaehliJ moved this from ✏️ Draft to 📋 Backlog in Pillarbox Feb 12, 2025
@StaehliJ StaehliJ moved this from 📋 Backlog to 👀 Follow in Pillarbox Feb 12, 2025
@Gustl22
Copy link
Author

Gustl22 commented Feb 12, 2025

So we have following problem:

As I develop a plugin for flutter to abstract this functionality of analytics, we need to hand over the params via a method channel. This can only happen as soon as the android part of the app is already running and not during Application initialization, as it is needed to have the communication channels present, before any interaction from Flutter to Kotlin can take place. So it gets called during a later lifecycle step:

https://github.com/SRGSSR/transombox_flutter/blob/689ca97c4a9b5d1430d4b05345b05c4c8a3328c9/packages/srg_analytics/android/src/main/kotlin/ch/srgssr/srg_analytics/flutter/SrgAnalyticsPlugin.kt#L53

Flutter starts its lifecycle once the app is in foreground (unless you do some magic stuff messing with this, or explicitely want something to also run in the background). So regularly the code is initialized on every foreground event. It is also then possible to notice, as soon as the app goes in the background to e.g. unitialize native stuff.

There's also the ability to restore states, how it was previous to going in the background:
https://docs.flutter.dev/platform-integration/android/restore-state-android

For me it would be cleaner to unitialize the analytics and then initialize as soon as it's in the foreground instead of explicitely saving this state.
Another option would be a getter in the analytics tool to see, if the analytics already were initialized.

In general, I think it is always good practise to have the option to tidy up the things manually.

@StaehliJ
Copy link
Contributor

StaehliJ commented Feb 12, 2025

Do you know if it is executed into the same process, I hope so. SRGAnalytics is a Singleton responsible to init comscore library which uses dlls.

Do you try to put the init call between try catch?

try {
    initSRGAnalytics(config = config)    
} catch (e: IllegalArgumentException) { 
    e.printStackTrace()
 }

So first time it initialize and the second times it does nothing because it is already initiialized.

@StaehliJ
Copy link
Contributor

StaehliJ commented Feb 12, 2025

Are you sur you can create a Android Application classe like it is done here ? : flutter/flutter#46329

package com.your.package.

import io.flutter.view.FlutterMain
import android.app.Application

class DemoApplication : Application() {
    override fun onCreate() {
        super.onCreate()

        initSRGAnalytics(config)

        FlutterMain.startInitialization(applicationContext)
    }
}

@Gustl22
Copy link
Author

Gustl22 commented Feb 12, 2025

I can indeed, in my user facing app:
So the code can be added in the platform initializization code (in kotlin) in my user facing app.
But that defeats the whole purpose of a package (and also Flutter in general), which tries to abstract native code to be usable in Flutter.

The information to initialize the SRG analytics are parameters, which need to be passed to the native code while the native app already has been initialized. Before the app does not have any information about its Flutter application (besides the things which are hardcoded / given natively).

To think in a bigger picture, this package abstraction is useful, as the initialization of SRGAnalytics only has to be done once for every user of the package. This abstraction then is applied to all platforms: android, ios, web and in further scenarios also linux and windows. So a Flutter dev does not need to deal with platform code (in 6 languages), and rather just calls this method in Flutter, which works for every platform out of the box.

@Gustl22
Copy link
Author

Gustl22 commented Feb 12, 2025

So first time it initialize and the second times it does nothing because it is already initiialized.

Yes, that's exactly how we currently manage the code right now. Non-the-less, it's a bug and the root cause should be properly handled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: 👀 Follow
Development

No branches or pull requests

2 participants