TIP

Crasheye Unity Plugin是专为基于Unity引擎的游戏APP而开发的异常监控插件,它能够自动捕获Unity项目中脚本(如JavaScript、C#)和本地代码(如Objective-C、Java)抛出的异常,并提供实时、准确的错误分析服务。

# 1.工具下载

在SDK下载页面点击 下载Crasheye Unity Plugin

# 2.导入Crasheye Unity Plugin

  • 下载完成后,直接将Package拖拽到项目中

# 3.初始化

# Android

(注意:如果Unity为2018.2及以下版本,初始化方法请查看 Unity2018.2及以下版本Android初始化步骤)

从Unity2018.2版本以后,Unity已经可以直接编译 .cpp、.a、.java 文件作为 插件 在Unity程序中使用了,可以节省下使用VS、AS、XCode进行插件开发的导出调试的步骤,十分方便。

如果项目使用的Unity版本高于Unity2018.2版本,可以直接在项目的Plugins/Android目录下新建一个Java文件,这里起名叫MainActivity.java

可将以下代码粘贴到MainActivity.java

package com.crasheye.client.api.unity3d;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;

import com.unity3d.player.UnityPlayerActivity;
import com.xsj.crasheye.Crasheye;

public class MainActivity extends UnityPlayerActivity {
    public static String TAG = "MonoCrasheye";
    
    String Crasheye_appkey = null;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        try {
            ApplicationInfo info = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            Crasheye_appkey = info.metaData.getString("Crasheye_appkey");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        
        if (Crasheye_appkey == null) {
            Log.e(TAG,"appkey is Empty");
        } else {
            Crasheye.initWithMonoNativeHandle(this, Crasheye_appkey);
        }
    }
}

AndroidManifest.xml文件的application标签内添加两条meta-data标签。用于指定Crasheye上传数据的应用appkey。

<application>
    <meta-data
        android:name="Crasheye_appkey"
        android:value="应用appkey" />
</application>

接着修改Unity项目中的AndroidManifest.xml文件,设置入口为刚刚打好的 activity即可。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.unity3d.player">

    <uses-feature android:glEsVersion="0x00030000" />
    <uses-feature
        android:name="android.hardware.vulkan.version"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch.distinct"
        android:required="false" />

    <application>
        <activity
            android:name="com.crasheye.client.api.unity3d.MainActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
            android:hardwareAccelerated="false"
            android:launchMode="singleTask"
            android:screenOrientation="fullSensor"
            android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="android.notch_support"
                android:value="true" />
        </activity>
        <meta-data
            android:name="unity.splash-mode"
            android:value="0" />
        <meta-data
            android:name="unity.splash-enable"
            android:value="True" />
        <meta-data
            android:name="notch.config"
            android:value="portrait|landscape" />
        <meta-data
            android:name="unity.build-id"
            android:value="38c4abce-dfeb-493b-9906-c63646cacb76" />
    </application>
</manifest>

# Android初始化注意事项

在你的Unity工程中打开 [Build Setting] 面板,选择Android平台,点击 [Player Settings...] ,切换到 [Setting for Android] 选项卡,在 [Other Settings] 栏修改 [Internet Access] 选项为 [Require] 状态。

请确保Unity导出后的Android工程中,AndroidManifest.xml文件加入了下列相应的 Android权限申明 。 若已添加,请勿重复加入。

<!--权限配置,必需> 
<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.READ_LOGS" /> 

# IOS

IOS 在程序入口添加Unity的初始化脚本:(使用此接入必需把Crasheye.cs从对象上去除。

void Start()
{
        #if UNITY_ANDROID
                // 程序入口还需要初始化捕获脚本异常
                Crasheye.RegisterLogCallback();
        #endif

        #if UNITY_IPHONE
                /**
                * iOS 初始化是在Unity里完成 
                */
                Crasheye.StartInitCrasheye("请填写iOS AppKey");
        #endif
}

# iOS 相关配置

若你的应用不会发布到iOS平台则忽略此步骤。
在Unity导出后的iOS工程中,为工程添加编译选项(若已添加,请勿重复加入):

打开你的XCode工程设置,在[Build Phases]项中展开[Link Binary With Libraries],点击[+]按钮

[libz.dylib][libc++.dylib]添加进来:

至此,Unity项目的iOS工程配置就完成了。

请在真机上调试验证,在Crasheye后台便能实时看到监控数据。

iOS SDK版本2.5.0及以上,已将上传改为https方式,不需再添加NSExceptionDomains或NSAllowsArbitraryLoads字段,2.5.0以下版本需自行添加例外。

# 测试

请在真机上调试验证,在Crasheye后台便能实时看到监控数据。 直接运行工程,您能在logcat里看到如下的日志信息,就代表你的初始化已经成功:

# iOS SDK在MONO模式下的接入

iOS版本的SDK默认支持的模式为IL2CPP,如有特殊需要,必须在mono模式接入,参考以下说明:
(若你的应用使用IL2CPP模式,则忽略此步骤。)

  1. CrasheyeForIOS.cs的 public static void Init(string appKeyForIOS, string channIdForIOS)中,注释掉:
crasheyeInitWithChannel(appKeyForIOS, channIdForIOS);
  1. 在项目导出的xcode工程的main.mm中,加入函数声明:
extern "C" void mono_set_signal_chaining(int chain_signals);
extern "C" void crasheyeInitWithChannel(const char * appkey, const char * channel);
  1. 在项目导出的xcode工程的main.mm的main函数中:NSAutoreleasePool* pool = [NSAutoreleasePool new]; UnityInitTrampoline();间加入以下语句
mono_set_signal_chaining(1);
//"appkey","channel"应被你项目的实际appkey和channel替换
crasheyeInitWithChannel("appkey","channel");
  1. 测试, 请在真机上调试验证,在Crasheye后台便能实时看到监控数据。

# 4.接入完成

完成上述步骤后,Crasheye Unity Plugin工具接入完成。

# Unity2018.2及以下版本Android初始化步骤

TIP

❗️ 如果项目使用的Unity版本在Unity2018.2版本及以下,则需要进行以下操作进行接入
Crasheye android 的初始化必须在java层中进行,因此可以执行下述步骤

# 1).在Unity中导出Android工程

在安卓构建选项中勾选Export Project,点击Export即可导出Android项目

注:如果选择的构建平台不是Android平台,先点击Switch platform切换到Android平台

# 2).新建Empty Activity

  • 打开导出的Android项目,并(Unity 2019的版本需要在unity Library下)新建一个新的Empty Activity,位置和名称随意
  • 此处起名为MainActivity,位置为com.crasheye.client.api.unity3d
  • 截图中使用的IDEAndroid Studio

注:新的Activity不需要界面文件,语言选择Java

# 3).Crasheye 初始化配置(二选一)

将继承类改为UnityPlayerActivity,并进行Crasheye初始化的配置,详见下述代码

如果项目中的主Activity继承于 UnityPlayerActivity, 则请务必将Crasheye初始化代码放在 super.onCreate() 之后。

因为在super.onCreate()中会调用 new UnityPlayer(),而因为新版本的Unity有处理崩溃信号,因此必须先让Unity初始化,再初始化Crasheye,以便使得Crasheye能先捕获到崩溃信号。

注:如果项目有接入XG SDK,则需要将继承类修改为XGUnityActivity,由于XG SDK 继承了UnityPlerActivity,因此只要继承XG的即可。
以下代码中应用appkey填上自己的应用Appkey,Appkey可在权限平台 (opens new window)申请。

# ① 在jar包中配置参数

该方法有个缺点,如果国内海外不同参数配置,或同一个项目在区分地区时候,想使用不同appkey,都需要重新生成jar包

package com.crasheye.client.api.unity3d;

import android.os.Bundle;
import com.unity3d.player.UnityPlayerActivity;
import com.xsj.crasheye.Crasheye;

public class MainActivity extends UnityPlayerActivity {
    private String appkey = "应用AppKey"; //应用的appkey
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Crasheye.initWithMonoNativeHandle(this, appkey);
    }
}

这里的appkey填上自己所选项目下的应用appkey,appkey可在权限平台 (opens new window)申请。

# ② 在manifest 中配置参数(推荐)

建议修改成下面示例代码的形式。便于国内/ 海外不同参数的调用,不需要重新生成jar包

package com.crasheye.client.api.unity3d;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;

import com.unity3d.player.UnityPlayerActivity;
import com.xsj.crasheye.Crasheye;

public class MainActivity extends UnityPlayerActivity {
    public static String TAG = "MonoCrasheye";
    
    String Crasheye_appkey = null;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        try {
            ApplicationInfo info = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            Crasheye_appkey = info.metaData.getString("Crasheye_appkey");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        
        if (Crasheye_appkey == null) {
            Log.e(TAG,"appkey is Empty");
        } else {
            Crasheye.initWithMonoNativeHandle(this, Crasheye_appkey);
        }
    }
}

这样就把设置Crasheye上传数据的服务器域名和项目的appkey放到了AndroidManifest.xml文件里去完成。之后修改配置,可以直接在AndroidManifest.xml中进行修改,不需要重新导出项目打jar包。

AndroidManifest.xml文件的application标签内添加两条meta-data标签。用于指定Crasheye上传数据项目的appkey。

<application>
    <meta-data
        android:name="Crasheye_appkey"
        android:value="项目的appkey" />
</application>

# 4).将第2步中新建的Activity打包成jar

# Android Studio打包成jar包

build.gradle文件中,添加一个Jar Task。用于使打出来的Jar包去除掉BuildConfig文件

task makeJar(type: Jar, dependsOn: ['build']) {
    destinationDir = file('build/outputs/jar/')
    baseName = "MonoCrasheye"
    //from('build/intermediates/classes/debug')
    from('build/intermediates/javac/debug/compileDebugJavaWithJavac/classes')
    include('com/crasheye/**/*.class')
}

build.gradle添加配置后,务必要点击Sync Now按钮

点击Gradle按钮,弹出Gradle菜单。打开如下图所示的路径

找到刚才创建的Jar Task右键执行该Task即可完成打包

打包好的jar包名字叫MonoCrasheye.jar,在该Activity所处的Librarybuild/outputs/jar路径下。

# Eclipse打包成jar包

把src工程导出成jar包

导出时把所有文件都去除,只选择src进行导出,如导出文件为:MonoCrasheye.jar

# 5).导入Unity 工程

把Jar包放在Unity项目的Plugins\Android目录中

接着修改Unity项目中的AndroidManifest.xml文件,设置入口为刚刚打好的 activity即可。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.unity3d.player">

    <uses-feature android:glEsVersion="0x00030000" />
    <uses-feature
        android:name="android.hardware.vulkan.version"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch"
        android:required="false" />
    <uses-feature
        android:name="android.hardware.touchscreen.multitouch.distinct"
        android:required="false" />

    <application>
        <activity
            android:name="com.crasheye.client.api.unity3d.MainActivity"
            android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
            android:hardwareAccelerated="false"
            android:launchMode="singleTask"
            android:screenOrientation="fullSensor"
            android:theme="@style/UnityThemeSelector">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="unityplayer.UnityActivity"
                android:value="true" />
            <meta-data
                android:name="android.notch_support"
                android:value="true" />
        </activity>
        <meta-data
            android:name="unity.splash-mode"
            android:value="0" />
        <meta-data
            android:name="unity.splash-enable"
            android:value="True" />
        <meta-data
            android:name="notch.config"
            android:value="portrait|landscape" />
        <meta-data
            android:name="unity.build-id"
            android:value="38c4abce-dfeb-493b-9906-c63646cacb76" />
    </application>
</manifest>

# 6).接入完成

把导出的 jarAndroidManifest.xml 文件放到 Unity工程的 Android 下 完成上述步骤后,Crasheye Unity Package中android 就已经完成

# 5.常用API

# Crasheye.sendScriptException

发送脚本异常

  • 此接口主要是给开发者主动调用,在捕获到的异常脚本信息时,如:lua、js等脚本异常,可以通过调用接口上报至服务端。
/**
* 发送脚本异常
* @param e 异常信息
*/
Crasheye.sendScriptException(Exception e);

# Crasheye.setFlushOnlyOverWiFi

设置是否仅在wifi下上报报告文件

  • 为了节省用户在非wifi环境下的网络流量,Crasheye提供接口可使崩溃后的堆栈信息仅在手机链接Wifi的情况下才上报:
/**
* 设置是否仅在wifi下上报报告文件
* @param enabled true表示仅在wifi下上报报告文件
*/
Crasheye.setFlushOnlyOverWiFi(bool enabled);

# Crasheye.SetAppVersion

设置App版本号

  • Crasheye默认读取配置文件中的版本信息,当然您也可以自己设置版本信息。
Crasheye.SetAppVersion(string youAppVersion);

# Crasheye.SetUserIdentifier

设置用户标识

  • 为每一条上报记录设置用户标识,可以方便后期筛选和定位问题,比如开发人员想看到自己手机上报的崩溃信息,就可以采用这种方式:
/**
* 设置用户标识
* @param userIdentifier 用户标识
*/
Crasheye.SetUserIdentifier("UserIdentifiter");

# Crasheye.SetChannelID

设置渠道号

  • 您可以使用此方法设置渠道号信息:
/**
* 设置渠道号
* @param ChannelID 渠道号
*/
Crasheye.SetChannelID("xxx");

# Crasheye.AddExtraData

添加自定义数据

  • 如果您觉得Crasheye默认捕获的数据还不足以满足您的要求的话,您可以添加自定义数据,只需要调用如下API即可:
/**
* 添加自定义数据
* @param key 自定义数据的标识符
* @param value 自定义数据的内容
*/
Crasheye.AddExtraData(string key, string value);

# Crasheye.leaveBreadcrumb

添加面包屑(打点信息)

  • 您可以在您的代码中添加多个面包屑(打点信息)然后在Crasheye平台上查看面包屑(打点信息)的时间和顺序,这样您就可以监视到您的项目是否按照您的预设跑了!只需要在每个您想监视的地方调用如下API即可(Android接口最大支持收集16行最新的面包屑):
Crasheye.leaveBreadcrumb(string breadcrumb);

# Crasheye.SetLogging

设置收集log日志

  • 此接口主要是收集运行中的logcat日志,当发现异常时会把收集到的log信息保存起来,并一同上传至服务器;(接口最大支持收集1000行最新的log日志) 接口只用于Android系统,iOS无法使用此功能;
/**
* 获取应用程序log日志(过滤条件:关键字过滤+行数)
* @param lines  获取的行数(最大收集1000行)
* @param filter 获取的关键字(可不传) 。例如:filter 是"Crasheye"就相当于LogCat过滤栏中输入“logcat -d Crasheye”
*/
Crasheye.SetLogging(lines, filter);
or
Crasheye.SetLogging(lines);

# Crasheye.SetRegisterLogFunction

设置注册日志回调函数

  • 日志回调函数 Application.RegisterLogCallback,因为此接口已经在Crashye里先初始化了一次,如果应用程序也需要使用日志回调方法,可以使用此接口,把需要执行的函数Set进来就可以了;
/**
* 设置注册日志回调函数
* @param RegisterLog     需要回调的函数
*/
Crasheye.SetRegisterLogFunction(RegisterLog); 
//eq: 
void Start(){
    Crasheye.SetRegisterLogFunction(Test1);
}

[AOT.MonoPInvokeCallback(typeof(Crasheye.RegisterLog))]
public void RegisterLogFunction(string logString, string stackTrace, LogType type)
{
    //do something
}

# Crasheye.SetIsBetaVersion

设置测试版本

/**
* 设置该版本是否为测试版本
* @param isBeta 是否为测试版本(true or false)
*/
Crasheye.SetIsBetaVersion(isBeta)

# 6.可能会遇到的问题

# Gradle project sync failed.

遇到这种情况需要检查项目的local.properties文件是否使用Unity引擎的Android SDK路径。

如果是,请将SDK的路径更改为Android Studio的Android SDK路径。

一般情况下是C:\Users{你的用户名}\AppData\Local\Android\Sdk

修改后点击SDK Manager按钮,查看build.gradle文件中对应版本的Android SDK是否已经下载。

完成后,点击Try Again,如果Gradle project sync failed.消失了,说明构建成功了

# Type XXX is defined multiple times

先尝试Clean Project,再重新打包

如果还是报错,请检查jar包以及代码中是否有出现文件或类同名。

上次更新: 2024/3/2 00:46:56