Проблема с вызовом start () / stop () в каждом действии (как предполагает Кристиан) заключается в том, что это приводит к новому «посещению» для каждого действия, к которому переходит ваш пользователь. Если это нормально для вашего использования, тогда это нормально, однако большинство людей не ожидают, что посещения будут работать. Например, это очень затруднит сравнение номеров андроидов с номерами в сети или iphone, поскольку «посещение» в Интернете и iphone сопоставляет сеанс, а не страницу / действие.
Проблема с вызовом start () / stop () в вашем Приложении заключается в том, что это приводит к неожиданно долгим посещениям, поскольку Android не гарантирует прекращение работы приложения после закрытия вашего последнего действия. Кроме того, если ваше приложение выполняет какие-либо действия с уведомлениями или службами, эти фоновые задачи могут запустить ваше приложение и привести к "фантомным" посещениям. ОБНОВЛЕНИЕ: Стефано правильно указывает на то, что onTerminate () никогда не вызывается на реальном устройстве, поэтому нет очевидного места для вызова stop ().
Проблема с вызовом start () / stop () в одном «основном» действии (как предполагает Aurora) заключается в том, что нет гарантии, что это задание будет сохраняться в течение всего времени использования вашего приложения вашим пользователем. Если «основное» действие уничтожено (скажем, для освобождения памяти), ваши последующие попытки записать события в GA в других действиях потерпят неудачу, поскольку сеанс был остановлен.
Кроме того, в Google Analytics есть ошибка, по крайней мере, до версии 1.2, из-за которой она сохраняет четкую ссылку на контекст, который вы передаете в start (), не позволяя собирать мусор после его уничтожения. В зависимости от размера вашего контекста, это может быть значительная утечка памяти.
Утечка памяти достаточно легко исправить, ее можно устранить, вызвав start (), используя приложение вместо самого экземпляра действия. документы , вероятно, следует обновить, чтобы отразить это.
например. из вашей деятельности:
// Start the tracker in manual dispatch mode...
tracker.start("UA-YOUR-ACCOUNT-HERE", getApplication() );
вместо
// Start the tracker in manual dispatch mode...
tracker.start("UA-YOUR-ACCOUNT-HERE", this ); // BAD
Относительно того, когда вызывать start () / stop (), вы можете реализовать своего рода ручной подсчет ссылок, увеличивая счетчик для каждого вызова Activity.onCreate () и уменьшая для каждого onDestroy (), затем вызывая GoogleAnalyticsTracker.stop () когда счет достигает нуля.
Новая библиотека от Google EasyTracker позаботится об этом за вас.
В качестве альтернативы, если вы не можете создать подкласс действий EasyTracker, вы можете самостоятельно реализовать это вручную в своем собственном базовом классе действий:
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;
}
}