博客
关于我
(插播)unity的 异常捕捉和 ios Android 崩溃信息的捕捉。
阅读量:792 次
发布时间:2023-01-24

本文共 3634 字,大约阅读时间需要 12 分钟。

一个适合 iOS 和 Android 错误信息捕捉的 Unity 插件

随着应用程序的复杂性不断提升,开发者在日常工作中遇到崩溃和莫名错误的问题越来越频繁。这些问题不仅会导致用户体验下降,还可能导致应用在发布后面临用户投诉和bad sectors的风险。在此背景下,我开发了一个能够捕捉iOS和Android端的错误信息的Unity插件,旨在帮助开发人员更好地定位和解决问题。

背景介绍

在开发过程中,尤其是针对移动应用,应用程序的崩溃和异常处理是一个非常棘手的问题。与桌面应用程序相比,移动应用程序的资源更为受限,而开发者还需要确保在错误发生时能够快速处理,以避免用户流失。

对于iOS,尤其是 ZhObject-C 的编程特性,使得任何一个小错误都可能导致整个程序崩溃。类似地,Android端虽然更为包容,但在处理资源的管理上也可能出现意想不到的错误。因此,一个能够全方位捕捉操作系统、框架和应用程序本身错误的插件显得尤为必要。

该插件的主要功能

该插件基于以下原理,旨在为开发者提供一个全面的错误处理和信息收集框架:

  • 错误信息的捕捉:无论是应用程序突然的 crash,还是方向欺骗导致的不确定错误,这个插件都能够对相关信息进行捕捉和保存。
  • 设备信息的收集:包括设备型号、系统版本、运行环境等关键信息,帮助定位问题所在。
  • 错误堆栈和调用信息:对于iOS,捕捉 Objective-C 的错误堆栈信息;对于 Android,则捕捉其相关的 Throwable 对象。
  • 实现原理

    iOS 错误处理

    iOS 的异常处理机制基于其Objective-C语言特性,旨在为开发者提供一个广泛的错误信息处理框架。主要步骤包括:

    • 注册异常处理器:使用 NSSetUncaughtExceptionHandler 注册一个自定义的异常处理器,确保在未被捕获的异常发生时能够得到称为
    • 处理异常信息:在自定义异常处理器中,获取异常对象,并从中提取调用信息、堆栈信息和错误原因
    • 线程堵塞处理:确保在捕捉完错误信息后,进行适当的线程堵塞处理,以便能够及时上传错误信息

    Android 错误处理

    相较于iOS,Android 的错误处理机制更加简单,主要步骤如下:

    • 注册未捕获异常处理器:在 AndroidManifest.xml 中定义一个自定义的未捕获异常处理器类,确保在未被捕获的异常发生时调用相应的方法
    • 获取异常信息:获取 Throwable 对象,并从中提取相关错误信息
    • UI 线程处理:确保所有 UI 操作都在 UI 线程上执行,以避免因线程问题导致的新错误

    插件适配方法

    为了确保插件能够适配不同开发环境,以下方法被采用:

    • iOS 适配
      • 使用 C 的交叉调用技术通过 native 方法来实现错误信息的捕捉和处理
      • 在需要展示错误信息时,使用 UIAlertView 弹出提示框,供用户查看错误详情
    • Android 适配
      • 使用 Java Reflection 和 JNI 绑定 yawt 到 Unity 的错误信息捕捉机制
      • 确保所有 UI 操作都在 UI 线程上执行,以避免因线程问题导致的新错误

    具体实现细节

    错误信息的捕捉与处理

    对于iOS,捕捉的是 Objective-C 的错误堆栈信息,对于 Android则捕捉的是 Throwable 对象中的相关信息。具体实现如下:

    • iOS
      - (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);
      }
      }
    • Android
      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
      • Objective-C 语言
      • Core Foundation 和 CFRunLoop
      • NSException 处理逻辑
    • Android
      • Java语言
      • Android SDK 和 NDK
      • Reflection 和 JNI 绑定

    总结

    通过上述方法,我成功开发了一个能够适配iOS和Android的错误信息捕捉插件。该插件不仅能够快速定位应用程序的 crash 信息,还可以提取相关的调用堆栈和错误原因,便于开发和优化。在实际应用中,我还扩展了一些功能,如错误信息的本地存储和远程上传,确保开发人员能够快速获得所需的开发反馈。

    转载地址:http://rgeyk.baihongyu.com/

    你可能感兴趣的文章
    Ceph企业级实战
    查看>>
    Ceph存储引擎详解
    查看>>
    Ceph对象存储详解
    查看>>
    Cisco防火墙配置实战
    查看>>
    CISSP-安全与风险管理
    查看>>
    Clickhouse NoSQL数据库详解
    查看>>
    ContextLoaderListener自动装配配置信息
    查看>>
    DDNS动态域名无固定IPSEC配置实战
    查看>>
    DELL笔记本UEFI+GPT安装window10与Ubuntu双系统
    查看>>
    Docker+Jenkins+GIT CICD持续化集成实战
    查看>>
    Dockerfile 指令详解
    查看>>
    Docker安装MongoDB(附Docker虚拟机环境与MongoDB客户端连接工具)
    查看>>
    DRBD分布式存储解决方案实战
    查看>>
    DRBL+Clonezilla全自动批量安装操作系统
    查看>>
    DSMM数据安全概述
    查看>>
    Dva员工增删改查Demo实现-优化
    查看>>
    EasyUi的使用与代码编写(一)
    查看>>
    eclipse配置tomcat8.5报错The Apache Tomcat installation at this directory is version 8.5.4. A Tomcat
    查看>>
    eclipse配置xml的自动提示
    查看>>
    eclipse重置页面恢复到最初布局状态
    查看>>