Crash(应用崩溃)是由于代码异常而导致 App 非正常退出,导致应用程序无法继续使用,所有工作都停止的现象。发生 Crash 后需要重新启动应用(有些情况会自动重启),而且不管应用在开发阶段做得多么优秀,也无法避免 Crash 发生,特别是在 AndroID 系统中,系统碎片化严重、各 ROM 之间的差异,甚至系统BUG,都可能会导致Crash的发生。
在 AndroID 应用中发生的 Crash 有两种类型,Java 层的 Crash 和 Native 层 Crash。这两种Crash 的监控和获取堆栈信息有所不同。
Java CrashJava的Crash监控非常简单,Java中的Thread定义了一个接口: UncaughtExceptionHandler
;用于处理未捕获的异常导致线程的终止(注意:catch了的是捕获不到的),当我们的应用crash的时候,就会走 UncaughtExceptionHandler.uncaughtException ,在该方法中可以获取到异常的信息,我们通过 Thread.setDefaultUncaughtExceptionHandler 该方法来设置线程的默认异常处理器,我们可以将异常信息保存到本地或者是上传到服务器,方便我们快速的定位问题。
public class JavaCrashHandler implements Thread.UncaughtExceptionHandler { private static final String @R_404_6852@_name_SUFFIX = ".log"; private static Thread.UncaughtExceptionHandler mDefaultCrashHandler; private static Context mContext; private JavaCrashHandler() { } public static voID init(@NonNull Context context) { // 默认为:RuntimeInit#KillApplicationHandler mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler(); mContext = context.getApplicationContext(); Thread.setDefaultUncaughtExceptionHandler(new JavaCrashHandler()); } /*** 当程序中有未被捕获的异常,系统将会调用这个方法 ** @param t 出现未捕获异常的线程 * @param e 得到异常信息 */ @OverrIDe public voID uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) { try { // 自行处理:保存本地 @R_404_6852@ @R_404_6852@ = dealException(thread, throwable); // 上传服务器 // ...... } catch (Exception e1) { e1.printstacktrace(); } finally { // 交给系统默认程序处理 if (mDefaultCrashHandler != null) { mDefaultCrashHandler.uncaughtException(thread, throwable); } } } /*** 导出异常信息到SD卡 ** @param e */ private @R_404_6852@ dealException(Thread thread, Throwable throwable) { String time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); @R_404_6852@ crashFolder = new @R_404_6852@(mContext.getExternalCacheDir().getabsolute@R_404_6852@(), CrashMonitor.DEFAulT_JAVA_CRASH_FolDER_name); if (!crashFolder.exists()) { crashFolder.mkdirs(); } @R_404_6852@ crash@R_404_6852@ = new @R_404_6852@(crashFolder, time + @R_404_6852@_name_SUFFIX); try { // 往文件中写入数据 PrintWriter pw = new PrintWriter(new BuffereDWriter(new @R_404_6852@Writer(crash@R_404_6852@))); pw.println(time); pw.println(thread); pw.println(getPhoneInfo()); throwable.printstacktrace(pw); // 写入crash堆栈 pw.close(); } catch (IOException ex) { ex.printstacktrace(); } return crash@R_404_6852@; } private String getPhoneInfo() { PackageManager pm = mContext.getPackageManager(); PackageInfo pi = null; StringBuilder sb = new StringBuilder(); try { pi = pm.getPackageInfo(mContext.getPackagename(), PackageManager.GET_ACTIVITIES); // App版本 sb.append("App Version: "); sb.append(pi.versionname); sb.append("_"); sb.append(pi.versionCode + "\n"); } catch (PackageManager.nameNotFoundException e) { e.printstacktrace(); } // AndroID版本号 sb.append("OS Version: "); sb.append(Build.VERSION.RELEASE); sb.append("_"); sb.append(Build.VERSION.SDK_INT + "\n"); // 手机制造商 sb.append("vendor: "); sb.append(Build.MANUFACTURER + "\n"); // 手机型号 sb.append("Model: "); sb.append(Build.MODEL + "\n"); // cpu架构 sb.append("cpu: "); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LolliPOP) { sb.append(Arrays.toString(Build.SUPPORTED_ABIS)); } else { sb.append(Build.cpu_ABI); } return sb.toString(); }}
NDK Crash相对于Java的Crash,NDK的错误无疑更加让人头疼,特别是对初学NDK的同学,不说监控,就算是错误堆栈都不知道怎么看。
linux信号机制信号机制是linux进程间通信的一种重要方式,linux信号一方面用于正常的进程间通信和同步,另一方面它还负责监控系统异常及中断。当应用程序运行异常时,linux内核将产生错误信号并通知当前进程。当前进程在接收到该错误信号后,可以有三种不同的处理方式。
忽略该信号;捕捉该信号并执行对应的信号处理函数(信号处理程序);执行该信号的缺省 *** 作(如终止进程);当linux应用程序在执行时发生严重错误,一般会导致程序崩溃。其中,linux专门提供了一类crash信号,在程序接收到此类信号时,缺省 *** 作是将崩溃的现场信息记录到核心文件,然后终止进程。
总结以上是内存溢出为你收集整理的Android Carsh监控方案全部内容,希望文章能够帮你解决Android Carsh监控方案所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)