我一直在这个墙上撞墙几个小时。 Google Analytics的v4 docs指定了两种不同的方式让您的应用报告未捕获的异常。我无法工作。在这两种情况下,当我在我的应用程序中触发未捕获的异常(我自己的代码使用虚拟名称)时,我在LogCat中看到这样的行:
08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Tracking Exception: MyException (@MyClass:myMethod:143) {main}
08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete.
08-17 17:33:30.248: V/GAV4(8968): Thread[main,5,main]: Passing exception to original handler.
...然后是我的异常的堆栈跟踪,最后是:
08-17 17:33:44.282: I/Process(8968): Sending signal. PID: 8968 SIG: 9
从LogCat看,GA似乎从未真正将异常发送给Google的服务器!
如果有人设法在他们的Google Analytics控制台中报告未被捕获的异常,那么如果他们能够与我们分享他们是如何做到这一点的话,那就太棒了。我已经在其他人看到过这样的问题(例如,here和here),但没有确认报告未捕获的异常。
我在GA控制台中显示了屏幕视图,所以我必须做正确的事情。但不是未被捕获的例外。我假设一个人应该在行为>下寻找他们。崩溃和例外,我已将结束日期设置为今天(默认情况下似乎设置为昨天)。最后,在我的analytics_global_config.xml中,我有:
<integer name="ga_dispatchPeriod">1</integer>
因为否则默认值为1800秒,在这种情况下,我假设在GA控制台发生后至少30分钟内无法看到异常。 ga_dryRun
也是假的。
答案 0 :(得分:7)
正如@xitx所指出的那样,在人们设备上安装的Google Play服务库的更高版本中看起来像there's a bug。因为当我在模拟器上为相对较旧的设备(API 9,并且可能运行旧的Google Play服务库)运行现有代码时,崩溃确实会自动报告给GA的控制台。这是崩溃发生时LogCat所说的内容:
08-31 12:27:59.522: V/GAV4(335): Thread[GAThread,5,main]: Sending hit to store PATH: https: PARAMS: ul=en-us, ht=1409484468454, sr=480x800, a=746864705, sf=100.0, aid=com.redula.vsavings, cid=32da19a1-7e15-4c83-aaa9-f3f1d502b775, av=1.2, v=1, t=exception, an=Savings Organiser, tid=UA-XXXXXXXX, exd=NullPointerException (@HomeActivity:connectToInAppBillingService:202) {main}, _u=.2nKKhAAAL, exf=1,
08-31 12:27:59.622: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode initiated.
08-31 12:27:59.652: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode terminated.
08-31 12:27:59.652: V/GAV4(335): Thread[GAThread,5,main]: Dispatch running...
08-31 12:27:59.702: V/GAV4(335): Thread[GAThread,5,main]: User-Agent: GoogleAnalytics/3.0 (Linux; U; Android 2.3.1; en-us; sdk Build/GSI11)
08-31 12:27:59.702: V/GAV4(335): Host: ssl.google-analytics.com
08-31 12:27:59.702: V/GAV4(335): GET /collect?ul=en-us&ht=1409484468454&sr=480x800&a=746864705&sf=100.0&aid=com.redula.vsavings&cid=32da19a1-7e15-4c83-aaa9-f3f1d502b775&av=1.2&v=1&t=exception&an=Savings+Organiser&tid=UA-XXXXXXX&exd=NullPointerException+%28%40HomeActivity%3AconnectToInAppBillingService%3A202%29+%7Bmain%7D&_u=.2nKKhAAAL&_v=ma4.0.2&exf=1&qt=11249&z=2 HTTP/1.1
08-31 12:28:00.482: V/GAV4(335): Thread[GAThread,5,main]: sent 1 of 1 hits
08-31 12:28:00.492: V/GAV4(335): Thread[GAThread,5,main]: PowerSaveMode initiated.
08-31 12:32:48.562: I/Process(335): Sending signal. PID: 335 SIG: 9
这就是GA控制台在一分钟内发生的崩溃:
我知道你只能获得堆栈跟踪的第一行,但现在这对我有用。其他各种各样的人都有自己的方法来获取整个堆栈跟踪(例如,参见@ xitx&#39; s评论和here)。
因此,我计划使用现有代码并等待Google将修补程序发送到更高版本的Google Play服务中。一旦他们的修复程序发布,我的应用程序应该按原样运行。
为了记录,我在我的跟踪器的XML文件(res / xml / app_tracker_config.xml)中使用它:
<bool name="ga_reportUncaughtExceptions">true</bool>
我的getTracker()实现:
public class MyApp extends Application {
private static Tracker tracker = null;
synchronized Tracker getTracker() {
if (tracker == null) {
GoogleAnalytics analytics = GoogleAnalytics.getInstance(this);
analytics.enableAutoActivityReports(this);
tracker = analytics.newTracker(R.xml.app_tracker_config);
tracker.enableAdvertisingIdCollection(true);
}
return tracker;
}
}
然后在onCreate()中为我的主屏幕活动我这样做以初始化GA:
((MyApp) getApplication()).getTracker();
编辑(额外信息):全局配置文件,res / xml / analytics_global_config.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="ga_logLevel">verbose</string>
<integer name="ga_dispatchPeriod">1</integer>
<bool name="ga_dryRun">false</bool>
</resources>
我的应用程序的清单引用application
元素的子标记中的此文件:
<meta-data
android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="@xml/analytics_global_config" />
答案 1 :(得分:1)
只需在清单
中添加此内容即可<meta-data
android:name="com.google.android.gms.analytics.globalConfigResource"
android:resource="@xml/tracker.xml" />
之后你应该开始接收这个logcat:
V/GAV4﹕ Thread[main,5,main]: Tracking Exception: ArithmeticException (@MyActivity:onResume:111) {main}
V/GAV4﹕ Thread[main,5,main]: Dispatch call queued. Dispatch will run once initialization is complete.
V/GAV4﹕ Thread[main,5,main]: Passing exception to original handler.
重新启动应用程序后:
V/GAV4﹕ Thread[client_id_fetcher,5,main]: Loaded client id from disk.
V/GAV4﹕ Thread[main,5,main]: Loading Tracker config values.
V/GAV4﹕ Thread[main,5,main]: [Tracker] trackingId loaded: UA-XXXXXXXX-X
V/GAV4﹕ Thread[main,5,main]: [Tracker] session timeout loaded: 300000
V/GAV4﹕ Thread[main,5,main]: ExceptionReporter created, original handler is com.android.internal.os.RuntimeInit$UncaughtHandler
V/GAV4﹕ Thread[main,5,main]: Uncaught exceptions will be reported to Google Analytics.
V/GAV4﹕ Thread[GAThread,5,main]: connecting to Analytics service
V/GAV4﹕ Thread[main,5,main]: service connected, binder: android.os.BinderProxy@42175d30
V/GAV4﹕ Thread[main,5,main]: bound to service
V/GAV4﹕ Thread[GAThread,5,main]: connect: bindService returned true for Intent { act=com.google.android.gms.analytics.service.START cmp=com.google.android.gms/.analytics.service.AnalyticsService (has extras) }
V/GAV4﹕ Thread[main,5,main]: Connected to service
I/GAV4﹕ Thread[GAThread,5,main]: No campaign data found.
V/GAV4﹕ Thread[GAThread,5,main]: Initialized GA Thread
V/GAV4﹕ Thread[GAThread,5,main]: Loaded clientId
V/GAV4﹕ Thread[GAThread,5,main]: Loaded clientId
V/GAV4﹕ Thread[GAThread,5,main]: putHit called
V/GAV4﹕ Thread[GAThread,5,main]: Sending hit to service PATH: https: PARAMS: ul=en-us, ht=1408554996959, sr=720x1184, a=194292074, aid=<app package>, cid=9639b81c-b17a-4c3a-a43e-0c1f43a6d5c1, av=1.5.0.1, v=1, t=exception, an=<app name>, tid=UA-XXXXXXXX-X, exd=SQLiteBindOrColumnIndexOutOfRangeException (@MyApp:onCreate:185) {main}, _u=.nKhAAAL, exf=0
目前在我的项目中,我正在使用此代码(在Application.onCreate()方法中),它的工作正常:
GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(this);
applicationPreferences = new ApplicationPreferences(getApplicationContext());
tracker = googleAnalytics.newTracker(R.xml.tracker);
tracker.enableExceptionReporting(true);
String lastErrorString = applicationPreferences.getLastErrorString();
if (lastErrorString != null) {
applicationPreferences.clearLastErrorString();
tracker.send(new HitBuilders.ExceptionBuilder().setDescription(lastErrorString).setFatal(true).build());
}
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
applicationPreferences.setLastErrorString(Throwables.getStackTraceAsString(throwable));
defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);
}
});
注意:Throwables
是来自guava的类
没有番石榴的变异但没有完整的堆栈跟踪,只有原始行号和方法包含在报告中:
GoogleAnalytics googleAnalytics = GoogleAnalytics.getInstance(this);
applicationPreferences = new ApplicationPreferences(getApplicationContext());
tracker = googleAnalytics.newTracker(R.xml.tracker);
tracker.enableExceptionReporting(true);
String lastErrorString = applicationPreferences.getLastErrorString();
if (lastErrorString != null) {
applicationPreferences.clearLastErrorString();
tracker.send(new HitBuilders.ExceptionBuilder().setDescription(lastErrorString).setFatal(true).build());
}
final Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable throwable) {
applicationPreferences.setLastErrorString(
new StandardExceptionParser(getApplicationContext(), null).getDescription(thread.getName(), throwable)
);
defaultUncaughtExceptionHandler.uncaughtException(thread, throwable);
}
});
答案 2 :(得分:0)
对于offtopic很抱歉,但是从那个问题开始,我转而使用Crashlytics进行错误收集,它比GA更有效。