Google Analytics en la aplicación de Android: trata de múltiples actividades

Estaba bastante emocionado de ver lo fácil que es configurar Google Analytics con mi aplicación, pero la falta de documentación me tiene sentado con unas cuantas preguntas. La única información que puedo encontrar es la derecha de la documentación aquí , que sólo se ve en el informe de PageViews y eventos de una actividad. Quiero informar de PageViews y eventos a través de varias actividades en mi aplicación.

Ahora mismo en el onCreate () de todas mis actividades, estoy llamando:

tracker = GoogleAnalyticsTracker.getInstance(); tracker.start("UA-xxxxxxxxx", this); 

Y en la onDestroy () de todas mis actividades:

  tracker.stop(); 

Seguidamente, rastreo PageViews y eventos según sea necesario y los envío junto con otra solicitud HTTP que estoy realizando. Pero no estoy tan seguro de que sea la mejor manera. ¿Debería llamar a start () y stop () en cada actividad, o debería llamar a start () y stop () en mi actividad principal del lanzador?

El problema con llamar start () / stop () en cada actividad (como sugiere Christian) es que resulta en una nueva "visita" para cada actividad a la que el usuario acceda. Si esto está bien para su uso, entonces está bien, sin embargo, no es la forma en que la mayoría de la gente espera que las visitas funcionen. Por ejemplo, esto haría que comparar números androides a números web o iphone sea muy difícil, ya que una "visita" en la web y el iphone se correlaciona con una sesión, no una página / actividad.

El problema con la llamada start () / stop () en su aplicación es que resulta en visitas inesperadamente largas, ya que Android no ofrece garantías para finalizar la aplicación después de que se cierre su última actividad. Además, si tu aplicación hace algo con notificaciones o servicios, estas tareas de fondo pueden iniciar tu aplicación y dar lugar a visitas "fantasmas". ACTUALIZACIÓN: stefano señala correctamente que onTerminate () nunca se llama a un dispositivo real, por lo que no hay lugar obvio para poner la llamada a stop ().

El problema con la llamada start () / stop () en una sola actividad "principal" (como sugiere Aurora) es que no hay garantía de que la actividad se mantenga durante el tiempo que su usuario esté usando su aplicación. Si se destruye la actividad "principal" (por ejemplo, para liberar memoria), sus intentos subsiguientes de escribir eventos en la GA en otras actividades fallarán porque la sesión se ha detenido.

Además, hay un error en Google Analytics a través de al menos la versión 1.2 que hace que mantenga una referencia fuerte al contexto que se pasa a start (), evitando que se reciba basura recogida después de su destruido. Dependiendo del tamaño de su contexto, esto puede ser una fuga de memoria importante.

La fuga de memoria es bastante fácil de arreglar, se puede resolver llamando a start () utilizando la aplicación en lugar de la instancia de actividad en sí. Es probable que los documentos se actualicen para reflejar esto.

p.ej. From inside your Actividad:

 // Start the tracker in manual dispatch mode... tracker.start("UA-YOUR-ACCOUNT-HERE", getApplication() ); 

en lugar de

 // Start the tracker in manual dispatch mode... tracker.start("UA-YOUR-ACCOUNT-HERE", this ); // BAD 

En cuanto a cuándo llamar a start () / stop (), puede implementar una clase de recuento manual de referencia, incrementar un recuento para cada llamada a Activity.onCreate () y decrementar para cada onDestroy (), luego llamar a GoogleAnalyticsTracker.stop () cuando El conteo llega a cero.

La nueva biblioteca EasyTracker de Google se encargará de esto para usted.

Alternativamente, si no puede subclasificar las actividades de EasyTracker, puede implementarlo manualmente en su propia clase base de actividad:

 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; } } 

El SDK ahora tiene una biblioteca externa que se encarga de todo esto. Su llamado EasyTracker. Sólo puede importarla y ampliar la Actividad o ListActivity proporcionada, crear un recurso de cadena con su código y ya está.

El rastreador sólo rastrea la actividad donde se ejecuta. Entonces, ¿por qué no subclases una Actividad que empiece cada vez en onCreate :

 public class GAnalyticsActivity extends Activity{ public void onCreate(Bundle icicle){ super.onCreate(icile); tracker = GoogleAnalyticsTracker.getInstance(); tracker.start("UA-xxxxxxxxx", this); } // same for on destroy } 

A continuación, extiende esa clase para cada actividad que utilice:

 public class YourActivity extends GAnalyticsActivity{ public void onCreate(Bundle icicle){ super.onCreate(icile); // whatever you do here you can be sure // that the tracker has already been started } } 

El acercamiento que estoy utilizando es utilizar un servicio atado (sucede que utilizo uno ya estaba ahorrado la creación del código adicional de la placa de la caldera.)

Un servicio vinculado sólo durará mientras haya actividades vinculadas a él. Todas las actividades de mi aplicación se enlazan a este servicio, por lo que sólo dura el tiempo que el usuario está utilizando activamente mi aplicación, por lo tanto, una verdadera "sesión".

Inicie el rastreador con una instancia singleton de la aplicación que he extendido y agregado un método estático getInstance () para recuperar la instancia:

 // Non-relevant code removed public IBinder onBind(Intent intent) { tracker = GoogleAnalyticsTracker.getInstance(); tracker.startNewSession(PROPERTY_ID, MyApp.getInstance()); } public boolean onUnbind(Intent intent) { tracker.stopSession(); } 

Vea: http://developer.android.com/guide/topics/fundamentals/bound-services.html

Hice una división basada en el tiempo entre visitas en mi aplicación, funcionando así:

He construido un objeto wrapper singleton Tracker para el GoogleAnalyticsTracker donde mantengo la última vez que algo se rastreó. Si ese tiempo es más entonces x segundos lo trato como una nueva visita.

Por supuesto, esto sólo es útil si realiza un seguimiento de todo en su aplicación, y no puede ser la mejor solución en cada situación, funciona bien para mi aplicación sin embargo.

Sólo soporta trackPageView, pero setCustomVar y trackEvent deben implementarse fácilmente.

En cualquier lugar que necesite para realizar un seguimiento de algo simplemente agregue la línea:

  Tracker.getInstance(getApplicationContext()).trackPageView("/HelloPage"); 

Normalmente lo hago en el resumen de una actividad

Tracker

Necesitará algo como esto: http://mufumbo.wordpress.com/2011/06/13/google-analytics-lags-on-android-how-to-make-it-responsive/

Eso es en la versión anterior y solía funcionar muy bien. Ahora estoy en la misma lucha que tú, ya que V2 no parece ser muy consistente.

Me pregunto si esto es algo que se podría hacer usando AOP.

Android sólo puede utilizar la compilación de métodos AOP, así que tal vez algo como AspectJ?

Hay un poco más de información sobre el uso de AspectJ en Android en este hilo . El principal problema es que usted todavía tiene que declarar en las clases que posee.

  • GetDefaultTracker () de una clase que extiende InputMethodService?
  • No se puede ejecutar dex: varios archivos dex definen Lcom / google / android / gms / analytics / internal / Command
  • ¿Cómo puedo realizar un seguimiento de las impresiones de mi aplicación android en el sitio web de Google Play Store?
  • Google Analytics: vista web y vista de aplicaciones
  • Cómo trabajar con la dimensión personalizada en Google Analytics v3 para la aplicación para Android
  • Android Uso de Firebase Analytics junto con Google Analytics
  • Error al agregar Google Analytics
  • La medición de la campaña de Android no funciona
  • Com.google.android.feedback en Google Analytics
  • ¿Sólo un BroadcastReceiver por aplicación?
  • Falta de datos de comercio electrónico y código de seguimiento de eventos incorrectos
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.