I was pretty excited to see how easy it is to set up Google Analytics with my app, but the lack of documentation has me sitting with a few questions. The only information that I can find is right from the documentation here, which only looks at reporting PageViews and Events from one Activity. I want to report PageViews and Events across multiple Activities in my app.
Right now in the onCreate() of all of my activities, I am calling:
tracker = GoogleAnalyticsTracker.getInstance(); tracker.start("UA-xxxxxxxxx", this);
And in the onDestroy() of all of my activities:
tracker.stop();
I then track PageViews and Events as needed, and Dispatch them along with another HTTP request I am performing. But I'm not so sure this is the best way. Should I be calling start() and stop() in each activity, or should I only call start() and stop() in my main launcher activity?
Install tracking is automatically enabled in Analytics for Android apps. You don't have to do anything!
Use Tag Manager with Google Analytics and Firebase. To get the latest mobile app report features in Google Analytics, use Firebase in your Android and iOS apps. Once enabled in your app, Google Analytics will automatically collect and report on built-in events and user properties.
Typically, one activity in an app is specified as the main activity, which is the first screen to appear when the user launches the app. Each activity can then start another activity in order to perform different actions.
Go to Analytics and select the Analytics account you registered the app with. If you're unsure, look for the Analytics tracking ID in the google-services. json file you added to your project earlier. Copy that ID to the Analytics account search in the report drop-down.
The problem with calling start()/stop() in every activity (as suggested by Christian) is that it results in a new "visit" for every activity your user navigates to. If this is okay for your usage, then that's fine, however, it's not the way most people expect visits to work. For example, this would make comparing android numbers to web or iphone numbers very difficult, since a "visit" on the web and iphone maps to a session, not a page/activity.
The problem with calling start()/stop() in your Application is that it results in unexpectedly long visits, since Android makes no guarantees to terminate the application after your last activity closes. In addition, if your app does anything with notifications or services, these background tasks can start up your app and result in "phantom" visits. UPDATE: stefano properly points out that onTerminate() is never called on a real device, so there's no obvious place to put the call to stop().
The problem with calling start()/stop() in a single "main" activity (as suggested by Aurora) is that there's no guarantee that the activity will stick around for the duration that your user is using your app. If the "main" activity is destroyed (say to free up memory), your subsequent attempts to write events to GA in other activities will fail because the session has been stopped.
In addition, there's a bug in Google Analytics up through at least version 1.2 that causes it to keep a strong reference to the context you pass in to start(), preventing it from ever getting garbage collected after its destroyed. Depending on the size of your context, this can be a sizable memory leak.
The memory leak is easy enough to fix, it can be solved by calling start() using the Application instead of the activity instance itself. The docs should probably be updated to reflect this.
eg. from inside your Activity:
// Start the tracker in manual dispatch mode... tracker.start("UA-YOUR-ACCOUNT-HERE", getApplication() );
instead of
// Start the tracker in manual dispatch mode... tracker.start("UA-YOUR-ACCOUNT-HERE", this ); // BAD
Regarding when to call start()/stop(), you can implement a sort of manual reference counting, incrementing a count for each call to Activity.onCreate() and decrementing for each onDestroy(), then calling GoogleAnalyticsTracker.stop() when the count reaches zero.
The new EasyTracker library from Google will take care of this for you.
Alternately, if you can't subclass the EasyTracker activities, you can implement this manually yourself in your own activity base class:
public abstract class GoogleAnalyticsActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Need to do this for every activity that uses google analytics GoogleAnalyticsSessionManager.getInstance(getApplication()).incrementActivityCount(); } @Override protected void onResume() { super.onResume(); // Example of how to track a pageview event GoogleAnalyticsTracker.getInstance().trackPageView(getClass().getSimpleName()); } @Override protected void onDestroy() { super.onDestroy(); // Purge analytics so they don't hold references to this activity GoogleAnalyticsTracker.getInstance().dispatch(); // Need to do this for every activity that uses google analytics GoogleAnalyticsSessionManager.getInstance().decrementActivityCount(); } } public class GoogleAnalyticsSessionManager { protected static GoogleAnalyticsSessionManager INSTANCE; protected int activityCount = 0; protected Integer dispatchIntervalSecs; protected String apiKey; protected Context context; /** * NOTE: you should use your Application context, not your Activity context, in order to avoid memory leaks. */ protected GoogleAnalyticsSessionManager( String apiKey, Application context ) { this.apiKey = apiKey; this.context = context; } /** * NOTE: you should use your Application context, not your Activity context, in order to avoid memory leaks. */ protected GoogleAnalyticsSessionManager( String apiKey, int dispatchIntervalSecs, Application context ) { this.apiKey = apiKey; this.dispatchIntervalSecs = dispatchIntervalSecs; this.context = context; } /** * This should be called once in onCreate() for each of your activities that use GoogleAnalytics. * These methods are not synchronized and don't generally need to be, so if you want to do anything * unusual you should synchronize them yourself. */ public void incrementActivityCount() { if( activityCount==0 ) if( dispatchIntervalSecs==null ) GoogleAnalyticsTracker.getInstance().start(apiKey,context); else GoogleAnalyticsTracker.getInstance().start(apiKey,dispatchIntervalSecs,context); ++activityCount; } /** * This should be called once in onDestrkg() for each of your activities that use GoogleAnalytics. * These methods are not synchronized and don't generally need to be, so if you want to do anything * unusual you should synchronize them yourself. */ public void decrementActivityCount() { activityCount = Math.max(activityCount-1, 0); if( activityCount==0 ) GoogleAnalyticsTracker.getInstance().stop(); } /** * Get or create an instance of GoogleAnalyticsSessionManager */ public static GoogleAnalyticsSessionManager getInstance( Application application ) { if( INSTANCE == null ) INSTANCE = new GoogleAnalyticsSessionManager( ... ,application); return INSTANCE; } /** * Only call this if you're sure an instance has been previously created using #getInstance(Application) */ public static GoogleAnalyticsSessionManager getInstance() { return INSTANCE; } }
The SDK now has a external library which takes care of all of this. Its called EasyTracker. You can just import it and extend the provided Activity or ListActivity, create a string resource with your code and you are done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With