Google Analytics – NetworkOnMainThreadException при отправке в AsyncTask

Я должен внедрить Google Analytics в приложении, над которым я работаю. Я использую Android Studio.

Я еще не совсем уверен, если я должен реализовать отправку трекера из каждой операции, или если сделать это один раз в Application class достаточно, но это еще одна история. В настоящий момент Google Analytics реализована в Application class . Он пытается подключиться к чему-то (хотя я установил dryRun ), терпит неудачу, а затем ничего не говорит, если я не dryRun свое приложение к сбою. Затем я получаю NetworkOnMainThreadException об ошибке NetworkOnMainThreadException при NetworkOnMainThreadException отправки событий.

Где он пытается отправить события во время dryRun , вызывая NetworkOnMainThreadException не менее? Разве он не должен посылать все в Logcat, а на 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<Tracker, Void, Integer> { 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 (соответствующие разделы):

 <?xml version="1.0" encoding="utf-8"?> <resources> <integer name="ga_sessionTimeout">300</integer> <!-- Enable automatic Activity measurement --> <bool name="ga_autoActivityTracking">true</bool> <!-- The screen names that will appear in reports --> <screenName name="com.example.app.App"> Application </screenName> <string name="ga_sampleFrequency">300.0</string> <string name="ga_trackingId">UA-xxxxxxxx-1</string> <bool name="ga_reportUncaughtExceptions">true</bool> </resources> 

analytics_global_config.xml:

 <?xml version="1.0" encoding="utf-8"?> <resources> <bool name="ga_dryRun">true</bool> <string name="ga_logLevel">verbose</string> </resources> 

Манифест (соответствующие части):

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.app" android:versionCode="00" android:versionName="0.00" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <permission android:name="com.example.app.permission.C2D_MESSAGE" android:protectionLevel="signature" /> <uses-permission android:name="com.example.app.permission.C2D_MESSAGE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <meta-data android:name="com.google.android.gms.analytics.globalConfigResource" android:resource="@xml/analytics_global_config" /> <application android:name=".App" android:allowBackup="true" android:hardwareAccelerated="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > 

UPD: Благодаря @Bart Hofma, я понял, что я, вероятно, сбивал с толку о том, что мое приложение рушится. Мое приложение не сбой, когда GA пытается отправить события. Напротив, GA пытается отправлять события только тогда, когда мое приложение выходит из строя, в противном случае он остается тихим. И я неожиданно разбил приложение, чтобы узнать, что может сказать ГА. У меня есть пользовательский видеопроигрыватель, который отлично работает на реальных устройствах, но сбой на виртуальных машинах, поэтому, когда я хочу, чтобы мое приложение вышло из строя, я просто перехожу к игровой активности на виртуальной машине.

Вы должны вызывать аналитику google из потока. Здесь я использую код, с которым я работаю.

Поместите этот код внутри класса (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 («Домашняя активность»);

Надеюсь, вам понравится.

Я потратил день на поиск решения (у меня есть те же строки дампа потока) и вышло, что оно напрямую не связано с Google Analytics. Основной причиной была следующая строка: adView.destroy (); Где adView == null. Похоже, Google Analytics попыталась отправить это исключение и разбилась сама. Я нашел его, отключив Google Analytics.

Intereting Posts
NotifyItemChanged (int position) обновляет несколько элементов в RecyclerView Как программно отображать 5dp строк в TextView Проблема ширины экрана TableLayout для Android Результаты пользовательского кругового обнаружения в «java.lang.UnsupportedOperationException» при приостановке? Форма пустого списка Android Изменение значков в ActionBar динамически Android Studio: перенести сложный файл build.xml в build.gradle Флажки, показывающие один и тот же текст после переключения ориентации Android-экранная клавиатура скрывает Python Kivy TextInputs Как настроить панель действий Шерлока + плагин карты? Как исправить «Пропустите перетаскивание, поскольку мы ждем ответа WebCore на прикосновение» Почему нам нужно хранить данные Goefence в приложении Android? Как выбрать контактный номер из телефонной книги андроида в мою заявку? Создание текста одинакового размера на разных устройствах Material Design – панель инструментов AppCompat, не отображающая тень