Android에서 Unity 애플리케이션에 대한 크래시 처리는 크래시 핸들러가 체인처럼 연결되어 작동합니다. 체인의 시작 지점에 있는 크래시 핸들러는 먼저 크래시를 수신하며 크래시를 처리하고 크래시를 체인의 다음 크래시 핸들러로 전달할 수도 있습니다. 체인의 크래시 핸들러 순서는 설치 순서에 따라 정의됩니다. 먼저 설치된 크래시 핸들러는 크래시를 마지막에 수신하며, 마지막에 설치된 크래시 핸들러는 크래시를 첫 번째로 수신합니다. 기본적으로 Unity는 체인의 첫 번째 크래시 핸들러 역할을 합니다. 크래시를 처리하여 체인의 다음 크래시 핸들러(기본적으로 Android 시스템 크래시 핸들러)로 전달합니다.
Unity가 크래시에 다르게 반응하도록 설정하고 자체 커스텀 크래시 핸들러를 체인에 추가할 수도 있습니다. 이 페이지에서는 Unity가 크래시를 처리하는 데 사용하는 방식을 지정하고 커스텀 크래시 핸들러를 생성하는 방법을 설명합니다.
Unity의 기본 크래시 처리 동작을 사용하고 싶지 않은 경우 -androidChainedSignalHandlerBehavior 커맨드 라인 인자를 사용하여 Unity가 크래시에 반응하는 방식을 변경할 수 있습니다. 이 인수는 다음 값 중 하나를 사용합니다.
| 동작 값 | 설명 |
|---|---|
legacy |
네이티브 크래시가 발생하면 Unity가 크래시를 래핑하여 Java 예외를 발생시킵니다. Unity는 크래시를 설치된 크래시 핸들러나 기본 시스템으로 전달하지 않습니다. |
disabled |
네이티브 크래시가 발생하면 Unity는 이를 무시하고 Android는 해당 크래시를 체인의 다음 크래시 핸들러로 직접 전달합니다. 이는 커스텀 크래시 핸들러(설치된 경우) 또는 기본 시스템(설치되지 않은 경우)입니다. 참고: 이 값을 사용하면 Unity Cloud Diagnostics 같은 Unity 서비스가 더 이상 크래시를 처리하지 않고 보고하지 않습니다. |
이 커맨드 라인 인자를 Unity에 전달하는 방법에 대한 자세한 내용은 Unity 시작 인자 지정을 참조하십시오.
이 섹션에는 자체 크래시 핸들러를 생성하고 설정하는 방법에 대한 예시가 포함되어 있습니다. 이렇게 하려면 Unity의 레거시 크래시 처리 동작을 사용하면 안 됩니다. 자세한 내용은 Unity가 크래시를 처리하는 방식 지정을 참고하십시오.
다음 코드 샘플은 커스텀 크래시 핸들러를 보여 줍니다. IL2CPP 스크립팅 백엔드를 사용하는 경우 이 cpp 예시 파일을 Unity 프로젝트에 직접 넣을 수 있습니다. 그러면 Unity가 libil2cpp.cpp의 일부로 컴파일합니다. Mono 스크립팅 백엔드를 사용하는 경우 자체 공유 라이브러리를 컴파일하고 연결해야 합니다. 자세한 내용은 Android용 네이티브 플러그인 생성을 참조하십시오.
android_crash_handler.cpp
#include <android/log.h>
#include <jni.h>
#include <signal.h>
struct sigaction s_PreviousHandler;
bool s_SignalHandlerInstalled;
static void MyCustomHandler(int sig, siginfo_t* info, void* ucontext)
{
__android_log_print(ANDROID_LOG_VERBOSE, "CustomCrashHandler", "Handling signal %d", sig);
s_PreviousHandler.sa_sigaction(sig, info, ucontext);
}
extern "C" void InstallCustomSignalHandlers()
{
struct sigaction Action = {};
Action.sa_sigaction = MyCustomHandler;
// Note: Register more signals if you want.
Action.sa_flags = SIGSEGV;
sigaction(SIGSEGV, &Action, &s_PreviousHandler);
s_SignalHandlerInstalled = true;
}
extern "C" JNIEXPORT void Java_com_unity3d_player_UnityPlayerActivity_InstallCustomSignalHandlersFromJava()
{
InstallCustomSignalHandlers();
}
extern "C" void UninstallCustomSignalHandlers()
{
if (s_SignalHandlerInstalled)
{
sigaction(SIGSEGV, &s_PreviousHandler, nullptr);
s_SignalHandlerInstalled = false;
}
}
크래시 핸들러를 설치하고 Unity가 크래시를 처리하는 데 사용하도록 하려면 위의 cpp 파일에서 InstallCustomSignalHandlers 메서드를 호출합니다. C# 또는 Java 코드를 통해 이 작업을 수행할 수 있지만, Unity 플레이어가 초기화한 후 C# 코드가 실행되기 전에 크래시가 발생할 수 있으므로 Java에서 이 메서드를 호출하는 것이 가장 좋습니다.
다음 코드 샘플은 Java 코드에서 InstallCustomSignalHandlers 메서드를 호출하는 방법을 보여 줍니다. 프로젝트에 추가하려면 Java 파일을 플러그인으로 설치하거나(Java 또는 Kotlin 소스 플러그인 만들기 참조) 익스포트된 프로젝트의 기존 Java 파일을 수정할 수 있습니다.
참고: 이 메서드를 호출하는 위치에 따라 크래시 처리의 동작이 변경됩니다. mUnityPlayer = new UnityPlayer(this, this);가 포함된 코드 라인인 Unity 런타임 초기화 전에 호출하면 네이티브 크래시 중에 Unity의 크래시 핸들러가 먼저 실행되고 시그널 핸들러가 실행됩니다(Unity가 신호를 전달하는 경우). Unity 런타임 초기화 후에 InstallCustomSignalHandlers를 호출하면 네이티브 크래시 중에 핸들러가 먼저 실행되고 신호를 전달하는 것은 사용자의 책임입니다.
UnityPlayerActivity.java
...
public native void InstallCustomSignalHandlersFromJava();
static
{
System.loadLibrary("il2cpp");
}
// Setup activity layout
@Override protected void onCreate(Bundle savedInstanceState)
{
InstallCustomSignalHandlersFromJava();
...
mUnityPlayer = new UnityPlayer(this, this);
setContentView(mUnityPlayer);
mUnityPlayer.requestFocus();
}
...