使用CrashHandler获取应用的crash信息
来源:互联网 发布:dos运行多个java 编辑:程序博客网 时间:2024/05/28 23:20
android应用不可避免地会发生crash,也称之为崩溃,无论程序写的多完美,总是无法避免crash的发生,可能是由于android系统底层的bug,也可能是由于不充分的机型适配或者是糟糕的网络状况。当crash发生时,系统会kill掉正在执行的程序,现象就是闪退或者提示用户程序已经停止运行,这对用户来说是很不友好的,也是开发者不愿意看到的。更糟糕的是,当用户发生了crash,开发者却无法得知程序为何crash,即便开发人员想去解决这个crash,但是由于无法知道用户当时的crash信息,所以往往也无能为力。
幸运的是,android提供了处理这类问题的方法,在Thread类中有这么一个方法setDefaultUncaughtExceptionHandler()就可以解决上述问题。当crash发生的时候,系统就会回调UncaughtExceptionHandler的UncaughtException方法,在UncaughtException方法中就可以获取到异常信息,可以选择把异常信息存储到SD卡中,然后在合适的时机通过网络将crash信息上传到服务器,这样开发人员就可以分析用户crash的场景从而在后面的版本中修复此类crash。我们还可以在crash发生时,弹出一个对话框告诉用户程序crash,然后再退出,这样比闪退要温和一点。
实现步骤如下:
- 实现UncaughtExceptionHandler对象,在它的UncaughtException方法中获取异常信息并将其存储在SD卡中或是上传到服务器供开发人员分析
- 调用Thread的setDefaultUncaughtExceptionHandler()方法将它设置为线程默认的异常处理器,由于默认异常处理器是Thread类的静态成员,因此它的作用对象是当前进程的所有进程。
下面是一个典型的异常处理器的实现:
import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.os.Build; import android.os.Environment; import android.util.Log; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; /** * Created by ds on 2017/11/21 16:55 */ public class CrashHandler implements Thread.UncaughtExceptionHandler { private static final String TAG = "CrashRecorder"; private static final boolean DEBUG = true; private static final String PATH = Environment.getExternalStorageDirectory().getPath() + "/CrashRecorder/log"; private static final String FILE_NAME = "crash"; private static final String FILE_NAME_SUFFIX = ".trace"; private static CrashHandler sInstance = new CrashHandler(); private Thread.UncaughtExceptionHandler mDefaultCrashHandler; private Context mContext; public CrashHandler() { } public static CrashHandler getInstance() { return sInstance; } public void init(Context context) { mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler(this); mContext = context.getApplicationContext(); } /* 这是最关键的函数,当程序中有未被捕获的异常,系统将会自动调用#uncaughtException方法 Thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息 * */ @Override public void uncaughtException(Thread thread, Throwable ex) { } private void dumpExceptionToSDCard(Throwable ex)throws IOException{ //如果SD卡不存在或无法使用,则无法把异常信息写入SD卡 if(!Environment.getExternalStorageDirectory().equals(Environment.MEDIA_MOUNTED)){ if(DEBUG){ Log.w(TAG,"sdcard unmounded,skip dump exception"); return; } } File dir=new File(PATH); if(!dir.exists())dir.mkdirs(); long current=System.currentTimeMillis(); String time=new SimpleDateFormat("yyy-MM-dd HH:mm:ss").format(new Date(current)); File file=new File(PATH+FILE_NAME+time+FILE_NAME_SUFFIX); try { PrintWriter p=new PrintWriter(new BufferedWriter(new FileWriter(file))); p.println(file); dumpPhoneInfo(p); p.println(); ex.printStackTrace(p); p.close(); }catch (Exception e){ Log.e(TAG,"dump crash info failed"); } } private void dumpPhoneInfo(PrintWriter p) throws PackageManager.NameNotFoundException { PackageManager pm=mContext.getPackageManager(); PackageInfo pi=pm.getPackageInfo(mContext.getPackageName(),PackageManager.GET_ACTIVITIES); p.print("App version: "); p.print(pi.versionName); p.print('_'); p.println(pi.versionCode); //Android版本号 p.print("OS Version: "); p.print(Build.VERSION.RELEASE); p.print('_'); p.println(Build.VERSION.SDK_INT); //手机制造商 p.print("Vendor: "); p.println(Build.MANUFACTURER); //手机型号 p.print("Model: "); p.println(Build.MODEL); //CPU架构 p.print("CPU ABI:"); p.println(Build.CPU_ABI); } private void uploadExceptionToServer(){ //TODO Upload Excetion Message To Your Web Server } }
使用上述类:
public class MyApp extends Application { private static MyApp sInstance; public static MyApp getInstance() { return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance=this; //在这里为应用设置异常处理,然后程序才能获取未处理的异常 CrashHandler crashHandler=CrashHandler.getInstance(); crashHandler.init(this); } }
现在,程序就可以处理未处理的异常了,妈妈再我不用担心我的程序crash了。需要注意的是,代码中被crash的异常不会交给CrashHandler处理,CrashHandler只能收到那些未被捕获的异常。
- 使用CrashHandler获取应用的crash信息
- 使用CrashHandler来获取应用的Crash信息
- 使用CrashHandler来获取应用的oom crash信息
- 使用CrashHandler来获取应用的crash信息
- Android 使用 CrashHandler 来获取应用的 crash 信息
- 使用CrashHandler来获取应用的crash信息
- Android 使用CrashHandler获取应用的crash信息
- 使用CrashHandler来获取(收集)应用的crash信息
- 通过CrashHandler获取应用的crash信息
- 使用CrashHandler获取crash信息
- android 程序崩溃信息的收集【使用CrashHandler来收集应用的crash信息】
- 从框架到完整项目搭建,实战项目《约个球》(2)-框架搭建之使用CrashHandler来获取应用的Crash信息
- Android 获取应用Crash信息的方法
- Android中获取应用的crash信息
- 使用UncaughtExceptionHandler捕捉应用的crash信息
- CrashHandler的应用
- 使用CrashHandler来捕获Crash异常
- android 快速开发三、 获取应用的crash信息
- SEO小结
- 高亮
- 测试点总结。。。
- Android验证手机号码的
- JavaScript jQuery 中定义数组与操作及jquery数组操作
- 使用CrashHandler获取应用的crash信息
- jsp页面集成xhEditor文本编辑器
- 两张表SQL关联查询
- 关于组件化的一点思考
- css编写移动端switch开关
- 免费开源API接口管理工具eoLinker更新版本,增加了识别代码注释生成文档功能!
- [BZOJ] 1293
- 生成连续日期
- 第一次使用博客 贴一个JSP+SQL实现按日期查询留言的代码吧~