Google Analytics(分析) – 在AsyncTask中发送的NetworkOnMainThreadException

我必须在我正在处理的应用中实施Google Analytics。 我正在使用Android Studio。

我不太确定我是否应该从每个Activity实现发送跟踪器,或者如果在Application class执行一次就足够了,但这是另一个故事。 目前,Google Analytics在Application class 。 它尝试连接到某些东西(虽然我已设置dryRun ),失败,然后什么也没说,除非我导致我的应用程序崩溃。 然后,当它尝试调度事件时,我收到NetworkOnMainThreadException错误。

尝试在dryRun上调度事件的dryRun ,导致NetworkOnMainThreadException不会减少? 在dryRun上它不应该把所有东西都发送到dryRun吗? 我应该如何在dryRun上处理它而不是?

起初我尝试实现它,没有额外的AsyncTask类,假设我将所有内容转储到Logcat,但是当我第一次得到NetworkOnMainThreadException错误时,我实现了AsyncTask类。

logcat的:

 01-15 13:06:21.835 1787-1800/com.example.app W/GAV4﹕ Thread[GAThread,5,main]: Service unavailable (code=1), will retry. 01-15 13:06:26.847 1787-1808/com.example.app W/GAV4﹕ Thread[Service Reconnect,5,main]: Service unavailable (code=1), using local store. 01-15 13:07:12.695 1787-1787/com.example.app E/GAV4﹕ Thread[main,5,main]: Error dispatching all events on exit, giving up: android.os.NetworkOnMainThreadException at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117) at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.close(OpenSSLSocketImpl.java:926) at org.apache.http.impl.SocketHttpClientConnection.shutdown(SocketHttpClientConnection.java:183) at org.apache.http.impl.conn.DefaultClientConnection.shutdown(DefaultClientConnection.java:150) at org.apache.http.impl.conn.AbstractPooledConnAdapter.shutdown(AbstractPooledConnAdapter.java:169) at org.apache.http.impl.conn.AbstractClientConnAdapter.abortConnection(AbstractClientConnAdapter.java:378) at org.apache.http.impl.client.DefaultRequestDirector.abortConnection(DefaultRequestDirector.java:1031) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:530) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:509) at com.google.android.gms.analytics.ha(Unknown Source) at com.google.android.gms.analytics.ha(Unknown Source) at com.google.android.gms.analytics.ag.dispatch(Unknown Source) at com.google.android.gms.analytics.w.eD(Unknown Source) at com.google.android.gms.analytics.w.dispatch(Unknown Source) at com.google.android.gms.analytics.x$b.run(Unknown Source) at com.google.android.gms.analytics.x.dY(Unknown Source) at com.google.android.gms.analytics.GoogleAnalytics.dY(Unknown Source) at com.google.android.gms.analytics.ExceptionReporter.uncaughtException(Unknown Source) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693) at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690) at dalvik.system.NativeStart.main(Native Method) 

申请类(相关部分):

 public class App extends Application { private static App context = null; private static final String PROPERTY_ID = "UA-xxxxxxxx-1"; private GoogleAnalytics analytics; private Tracker t; public void onCreate() { super.onCreate(); if (context == null) context = (App) getApplicationContext(); try { analytics = GoogleAnalytics.getInstance(context); t = analytics.newTracker(R.xml.app_tracker); new SendTrackerInBg(t); } catch (Exception e) {e.printStackTrace();} } 

SendTrackerInBg:

 public class SendTrackerInBg extends AsyncTask { SendTrackerInBg(Tracker t) { this.execute(t); } @Override protected Integer doInBackground(Tracker... trackers) { try { trackers[0].send(new HitBuilders.AppViewBuilder().build()); return 0; } catch (Exception e) { e.printStackTrace(); return -1; } } } 

app_tracker.xml(相关部分):

   300  true   Application  300.0 UA-xxxxxxxx-1 true  

analytics_global_config.xml:

   true verbose  

清单(相关部分):

                

UPD:感谢@Bart Hofma,我意识到我可能会因为我的应用崩溃而感到困惑。 当GA尝试调度事件时,我的应用程序不会崩溃。 相反,GA只在我的应用程序崩溃时尝试调度事件,否则它会保持沉默。 我故意让我的应用程序崩溃,看看GA可能会说些什么。 我有一个自定义video播放器,可以在真实设备上正常工作,但在虚拟机上崩溃,所以当我希望我的应用程序崩溃时,我只是转到VM上的播放器Activity。

您必须从线程中调用Google Analytics。 在这里,我正在分享我正在使用的代码。

将此代码放在一个类中(MBGoogleAnalyticsManager.java)

  import android.content.Context; import com.google.android.gms.analytics.GoogleAnalytics; import com.google.android.gms.analytics.HitBuilders; import com.google.android.gms.analytics.Tracker; public class MBGoogleAnalyticsManager { private static final String TAG = "MBGoogleAnalyticsManager"; private static MBGoogleAnalyticsManager instance = null; public String PROPERTY_ID = "UA-28454545-2"; private Context context; private Tracker dataTracker; public static MBGoogleAnalyticsManager getInstance(Context c) { if(instance == null) { System.out.println("MBGoogleAnalyticsManager new instance is created"); instance = new MBGoogleAnalyticsManager(c); } else { System.out.println("MBGoogleAnalyticsManager instance is already avaiable"); } return instance; } private MBGoogleAnalyticsManager(Context c) { //super(c); context = c; GoogleAnalytics analytics = GoogleAnalytics.getInstance(context); dataTracker = analytics.newTracker(PROPERTY_ID); } //============================================================================== //========================== Send a screen view ================================= //================================================================================ public synchronized void sendGoogleAnalyticsSreenView(String screenName) { dataTracker.setScreenName(screenName); // Set screen name. //dataTracker.setAppName("MovieBuddy"); // We can send the application name [String](Optional) //dataTracker.setAppVersion("2.2"); // We can send the application version [String](Optional) //dataTracker.setLanguage("Eng"); // We can send the language [String](Optional) //dataTracker.setSessionTimeout(300); // We can set the time for the session time out [Long](Optional) dataTracker.send(new HitBuilders.AppViewBuilder() //.setNewSession() // If want to start a new session (Optional) .build()); System.out.println("Screen: "+screenName); } //============================================================================== //========================== Send A Click Event Hit ============================= //================================================================================ public synchronized void sendGoogleAnalyticsHitEvents(String screenName,String category,String action,String label) { dataTracker.setScreenName(screenName); dataTracker.send(new HitBuilders.EventBuilder() .setCategory(category) // Set the category of the event [String] .setAction(action) // Set the action has taken for the event [String] .setLabel(label) // Set the label of for the event [String] .build()); System.out.println("Hit Label: "+label); } //============================================================================== //========================== Send A Exception Event ============================= //================================================================================ public synchronized void sendGoogleAnalyticsException(String screenName,String ExceptionMethodName,String ExceptionLocation,boolean ExceptionFatal) { dataTracker.setScreenName(screenName); dataTracker.send(new HitBuilders.ExceptionBuilder() .setDescription(ExceptionMethodName + ":" + ExceptionLocation) // Send the exception details [String] //(Never send the e.message, as it contains personal info) .setFatal(ExceptionFatal) // Send true or false if fatal exception error [boolean] .build()); } //============================================================================== //================ Send A Social Event Interaction With target ================== //================================================================================ public synchronized void sendGoogleAnalyticsSocialInteractionWithTarget(String screenName,String SocialNetworkName,String SocialAction,String SocialTarget) { dataTracker.setScreenName(screenName); dataTracker.send(new HitBuilders.SocialBuilder() .setNetwork(SocialNetworkName) // Set the Social Network Name [String] .setAction(SocialAction) // Set the action [String] .setTarget(SocialTarget) // Set the target [String](Not a mandatory field) .build()); System.out.println("Target: "+SocialTarget); } //============================================================================== //============== Send A Social Event Interaction Without target ================= //================================================================================ public synchronized void sendGoogleAnalyticsSocialInteraction(String SocialNetworkName,String SocialAction) { dataTracker.send(new HitBuilders.SocialBuilder() .setNetwork(SocialNetworkName)// Set the Social Network Name [String] .setAction(SocialAction) // Set the action [String] .build()); } } 

现在你必须调用这个类实例,方法并提供调用类所需的数据,如下所示:

 private void sendScreenView(final String screenName) { new Thread(new Runnable() { @Override public void run() { analyticsManager = MBGoogleAnalyticsManager.getInstance(getApplicationContext()); analyticsManager.sendGoogleAnalyticsSreenView(screenName); } }).start(); } 

并调用此方法:

sendScreenView(“Home Activity”);

希望你会发现它很有帮助。

我浪费了一天的时间来搜索解决方案(我有相同的线程转储行),并发布它与Google Analytics没有直接关系。 根本原因是下一行:adView.destroy(); 其中adView == null。 似乎Google Analytics尝试发送此exception并自行崩溃。 我发现它完全取消了Google Analytics。