本文共 3634 字,大约阅读时间需要 12 分钟。
随着应用程序的复杂性不断提升,开发者在日常工作中遇到崩溃和莫名错误的问题越来越频繁。这些问题不仅会导致用户体验下降,还可能导致应用在发布后面临用户投诉和bad sectors的风险。在此背景下,我开发了一个能够捕捉iOS和Android端的错误信息的Unity插件,旨在帮助开发人员更好地定位和解决问题。
在开发过程中,尤其是针对移动应用,应用程序的崩溃和异常处理是一个非常棘手的问题。与桌面应用程序相比,移动应用程序的资源更为受限,而开发者还需要确保在错误发生时能够快速处理,以避免用户流失。
对于iOS,尤其是 ZhObject-C 的编程特性,使得任何一个小错误都可能导致整个程序崩溃。类似地,Android端虽然更为包容,但在处理资源的管理上也可能出现意想不到的错误。因此,一个能够全方位捕捉操作系统、框架和应用程序本身错误的插件显得尤为必要。
该插件基于以下原理,旨在为开发者提供一个全面的错误处理和信息收集框架:
iOS 的异常处理机制基于其Objective-C语言特性,旨在为开发者提供一个广泛的错误信息处理框架。主要步骤包括:
NSSetUncaughtExceptionHandler
注册一个自定义的异常处理器,确保在未被捕获的异常发生时能够得到称为相较于iOS,Android 的错误处理机制更加简单,主要步骤如下:
Throwable
对象,并从中提取相关错误信息为了确保插件能够适配不同开发环境,以下方法被采用:
UIAlertView
弹出提示框,供用户查看错误详情对于iOS,捕捉的是 Objective-C 的错误堆栈信息,对于 Android则捕捉的是 Throwable
对象中的相关信息。具体实现如下:
- (void)caughtExceptionHandler:(NSException *exception) { NSString *currentTime = [self getCurrentTime]; CFRunLoopRef runLoop = CFRunLoopGetCurrent(); CFArrayRef allModes = CFRunLoopCopyAllModes(runLoop); NSArray *callStack = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; [dictionary setValue:callStack forKey:@"callStack"]; [dictionary setValue:reason forKey:@"reason"]; [dictionary setValue:name forKey:@"name"]; [dictionary setValue:currentTime forKey:@"time"]; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:nil]; if (jsonData.length > 0) { NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; // 如果网络条件满足: [[VKCatchCrash shareCatchCrash] performSelectorOnMainThread:@selector(uploadBug) withObject:nil waitUntilDone:YES]; while (!dismiss) { for (NSString *mode in (__bridge NSArray *)allModes) { CFRunLoopRunInMode((__bridge CFStringRef)mode, 0, false); } } CFRelease(allModes); NSSetUncaughtExceptionHandler(NULL); }}
public class MyCrashHandler implements UncaughtExceptionHandler { @Override public void uncaughtException(Thread thread, Throwable ex) { Throwable throwable = ex; StringBuilder message = new StringBuilder(); message.append("应用程序在 "); message.append(DateTimeFormatter.ofPattern("MM-dd HH:mm:ss").format(new Date(throwable_TC.getTime()))); message.append(" 发生了 crash! 原因: "); message.append(throwable.getCause().getMessage() != null ? throwable.getCause().getMessage() : "未捕获错误信息"); uploadCrashInfo(message.toString(), throwable.getStackTrace().join("\n")); }}
为了实现上述功能,我使用了以下工具和库:
通过上述方法,我成功开发了一个能够适配iOS和Android的错误信息捕捉插件。该插件不仅能够快速定位应用程序的 crash 信息,还可以提取相关的调用堆栈和错误原因,便于开发和优化。在实际应用中,我还扩展了一些功能,如错误信息的本地存储和远程上传,确保开发人员能够快速获得所需的开发反馈。
转载地址:http://rgeyk.baihongyu.com/