国内Android开发者应该主要使用友盟做数据统计分析,但个人在开发中发现这货越来越不靠谱,错误分析和事件统计数据时有时无,或者数据大起大落;甚至统计到的错误信息还包含友盟SDK自己的错误。跟他们客服和技术也沟通过,要么是让你发apk包,要么是让你自己看文档,问题始终没得到解决,然后很自然想到国外的类似工具。

Crashlytics在国外用的比较多,特别是iOS平台。Square、Walmart、Paypal、Yammer、Yelp、Path、Expedia、Waze、Groupon等众多大咖级别的APP都是其用户,而且目前也开始支持Android平台。而其他同类产品localytics、geckoboard等要么不支持Android、要么收费、要么没什么人用。

第一次用过之后的感受就是:高端、大气、上档次:

1.注册需要审核通过才能使用,国内同类产品顶多发个邮箱激活链接;

2.支持Eclipse、Intellij IDEA和Android Studio等三大IDE;

3.Eclipse插件是iOS主题风格UI,跟其他plugin在一起简直是鹤立鸡群;

4.只要登录帐号并选择项目,会自动导入jar包并生成一个序列号,然后在AndroidManifest.xml和启动Activity的入口添加初始化代码,可以说是一键式操作,当然要使用除错误统计外的其他功能还是得自己添加代码;

5.不像友盟等国内同类产品,将固定的序列号直接写入xml文件,而是动态自动生成的;当然这个存放序列号的xml文件也是不能修改和提交到版本控制系统的;

6.后台可以设置邮件提醒,当然这个最好不要开启,Android开发那数量惊人、千奇百怪的错误信息你懂的。

7.不仅能统计到UncaughtException这种未捕获的Crash异常信息,只要在try/catch代码块的catch中添加一行代码就能统计到任何异常;



try{
  myMethodThatThrows();
}catch(Exception e){
  Crashlytics.logException(e);
  //handle your exception here! 
}



8.相当详细的错误信息,不仅仅是简单的打印StackTrace信息;并且能看到最近一次crash的机器可用内存等信息,而不仅仅是简单统计机型和版本号。

虽然看起来很强大,一开始使用还是遇到了两个问题:

自定义UncaughtExceptionHandler和Crashlytics相冲突

一开始肯定想看看错误统计的即时性,通过手动添加代码throw newRuntimeException模拟crash,但是后台始终看不到错误数据。

然后只能看官方文档上找答案。发现有一篇讲怎么强制crash的文章,但仔细一看也没什么,只要在Crashlytics.start()调用之后就行了。

正在茫然的时候,想到了UncaughtExceptionHandler,之前有篇文章专门讲怎么通过它捕获应用全局异常信息。很显然,这种错误统计工具应该也是这么干的。

这样的话,很有可能是我们自定义的UncaughtExceptionHandler跟Crashlytics的SDK中定义的相冲突了,于是注释掉了自己的这部分代码,最后终于从后台看到错误日志了。

虽然友盟也是默认下次启动时上传错误信息,但感觉Crashlytics可靠多了,而且还是墙外的东西,做到这水平真心不容易了。

不过有个小问题,当初自己捕获异常只是kill掉当前的进程:



android.os.Process.killProcess(android.os.Process.myPid());



这样做不会影响之前的页面,但默认的处理方式是直接杀掉整个应用,这样对用户体验肯定有些影响,但为了能可靠的统计到所有异常信息,也只能做点牺牲了。
经过几天观察,Crashlytics统计到的错误信息数量确实比友盟更多,看来没选错。

Crashlytics初始化的时机

默认情况下,Eclipse插件会自动通过AndroidMafifest.xml找到用于launch的Activity,然后在其onCreate()方法中调用Crashlytics.start()完成初始化。显然这是个单例模式,只需要初始化一次。当然,你在每个Activity中都掉用一次也是没有问题的。
那如果我们自定义了Application子类,能否直接在其中初始化呢,答案是肯定的,详见这篇文章。

但后面还是出现了一个问题,有用户反馈新版本安装后移动时就crash了,而Crashlytics后台却看不到该信息。那么很显然是在Crashlytics初始化之前就出现了异常。
我们在Library Project中定义了一个BaseApplication extendsApplication,然后在实际项目中又定义了一个MyApplication extendsBaseApplication,而我们是在MyApplicationonCeate()方法中初始化Crashlytics的,而且还是在调用父类BaseApplicationonCreate()方法之后,通过logcat看到异常正是在BaseApplicationonCreate()方法中发生的,这时候Crashlytics还没初始化,当然也就统计不到数据了。
这说明我们Crashlytics初始化的时机不对,需要将Crashlytics代码放到BaseApplicationonCreate()中执行。






=============

libs导包

登录帐号并选择项目,会自动导入jar包并生成一个序列号,然后在AndroidManifest.xml和启动Activity的入口