From fa3f4a2ddec237bbec20d9f3b2236ee82e814766 Mon Sep 17 00:00:00 2001 From: Zihe Jia <zihe.jia@mixpanel.com> Date: Sat, 20 Jan 2024 16:07:26 -0800 Subject: [PATCH 1/2] make MPConfig no longer a Singleton in favor of supporting multiple configs --- .../android/mpmetrics/MPConfigTest.java | 16 +++++++++- .../mixpanel/android/mpmetrics/MPConfig.java | 32 ++++++++++++------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java index 67318a2bb..85fcdd883 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java @@ -12,6 +12,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.util.UUID; + @RunWith(AndroidJUnit4.class) public class MPConfigTest { @@ -138,7 +140,19 @@ public void testSetEnableLogging() throws Exception { assertFalse(config.DEBUG); } - + @Test + public void testMulptipleConfigs() { + String fakeToken = UUID.randomUUID().toString(); + MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false); + mixpanel1.setServerURL("https://api-eu.mixpanel.com"); + assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint()); + + String fakeToken2 = UUID.randomUUID().toString(); + MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false); + mixpanel2.setServerURL("https://api.mixpanel.com"); + assertEquals("https://api.mixpanel.com/track/?ip=1", mixpanel2.getEventEndpoint()); + assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint()); + } @Test public void testSetFlushBatchSize() { diff --git a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java index fcb7a0838..ca16076a8 100644 --- a/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java +++ b/src/main/java/com/mixpanel/android/mpmetrics/MPConfig.java @@ -96,16 +96,27 @@ public class MPConfig { // Name for persistent storage of app referral SharedPreferences /* package */ static final String REFERRER_PREFS_NAME = "com.mixpanel.android.mpmetrics.ReferralInfo"; - // Instances are safe to store, since they're immutable and always the same. + /** + * Retrieves a new instance of MPConfig with configuration settings loaded from the provided context. + * This method creates a new instance each time it is called, allowing for multiple configurations + * within the same application. + * + * Since version 7.4.0, MPConfig is no longer a Singleton, in favor of supporting multiple, + * distinct configurations for different Mixpanel instances. This change allows greater flexibility + * in scenarios where different parts of an application require different Mixpanel configurations, + * such as different endpoints or settings. + * + * It's important for users of this method to manage the lifecycle of the returned MPConfig instances + * themselves. Each call will result in a new configuration instance based on the application's + * metadata, and it's the responsibility of the caller to maintain any necessary references to these + * instances to use them later in their application. + * + * @param context The context used to load Mixpanel configuration. It's recommended to provide + * an ApplicationContext to avoid potential memory leaks. + * @return A new instance of MPConfig with settings loaded from the context's application metadata. + */ public static MPConfig getInstance(Context context) { - synchronized (sInstanceLock) { - if (null == sInstance) { - final Context appContext = context.getApplicationContext(); - sInstance = readConfig(appContext); - } - } - - return sInstance; + return readConfig(context.getApplicationContext()); } /** @@ -457,8 +468,5 @@ public String toString() { // Mutable, with synchronized accessor and mutator private SSLSocketFactory mSSLSocketFactory; private OfflineMode mOfflineMode; - - private static MPConfig sInstance; - private static final Object sInstanceLock = new Object(); private static final String LOGTAG = "MixpanelAPI.Conf"; } From a181e8da6dd2b3a533dadb607a349677e472186b Mon Sep 17 00:00:00 2001 From: Zihe Jia <zihe.jia@mixpanel.com> Date: Sat, 20 Jan 2024 21:35:22 -0800 Subject: [PATCH 2/2] test the settings(MPConfig) are not shared between mixpanel instances --- .../android/mpmetrics/MPConfigTest.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java index 85fcdd883..dec330382 100644 --- a/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java +++ b/src/androidTest/java/com/mixpanel/android/mpmetrics/MPConfigTest.java @@ -140,19 +140,6 @@ public void testSetEnableLogging() throws Exception { assertFalse(config.DEBUG); } - @Test - public void testMulptipleConfigs() { - String fakeToken = UUID.randomUUID().toString(); - MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false); - mixpanel1.setServerURL("https://api-eu.mixpanel.com"); - assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint()); - - String fakeToken2 = UUID.randomUUID().toString(); - MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false); - mixpanel2.setServerURL("https://api.mixpanel.com"); - assertEquals("https://api.mixpanel.com/track/?ip=1", mixpanel2.getEventEndpoint()); - assertEquals("https://api-eu.mixpanel.com/track/?ip=1", mixpanel1.getEventEndpoint()); - } @Test public void testSetFlushBatchSize() { @@ -174,6 +161,22 @@ public void testSetFlushBatchSize2() { assertEquals(5, mixpanelAPI.getFlushBatchSize()); } + @Test + public void testSetFlushBatchSizeMulptipleConfigs() { + String fakeToken = UUID.randomUUID().toString(); + MixpanelAPI mixpanel1 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken, false); + mixpanel1.setFlushBatchSize(10); + assertEquals(10, mixpanel1.getFlushBatchSize()); + + String fakeToken2 = UUID.randomUUID().toString(); + MixpanelAPI mixpanel2 = MixpanelAPI.getInstance(InstrumentationRegistry.getInstrumentation().getContext(), fakeToken2, false); + mixpanel2.setFlushBatchSize(20); + assertEquals(20, mixpanel2.getFlushBatchSize()); + // mixpanel2 should not overwrite the settings to mixpanel1 + assertEquals(10, mixpanel1.getFlushBatchSize()); + } + + @Test public void testSetMaximumDatabaseLimit() { final Bundle metaData = new Bundle();