Обработка сбоев Android
Обработка сбоев для приложений Unity на Android работает как цепь обработчиков сбоев. Обработчик сбоев в начале цепи получает сбой первым, и он может обрабатывать сбой, а также передавать сбой следующему обработчику сбоев в цепи. Порядок обработчиков сбоев в цепи определяется порядком их установки. Обработчик сбоев, установленный первым, является последним, который получает сбой, а обработчик сбоев, установленный последним, является первым, который получает сбой. По умолчанию Unity действует как первый обработчик сбоев в цепи. Он обрабатывает сбои и передаёт их следующему обработчику сбоев в цепи, который по умолчанию является системным обработчиком сбоев Android.
Вы можете настроить Unity так, чтобы он реагировал на сбои по-разному, а также добавить свой собственный обработчик сбоев в цепь. На этой странице объясняется, как указать метод, используемый Unity для обработки сбоев, и как создать собственный обработчик сбоев.
Указать, как Unity обрабатывает сбои
Если вы не хотите использовать поведение Unity по умолчанию, вы можете использовать аргумент командной строки -androidChainedSignalHandlerBehavior, чтобы изменить реакцию Unity на сбои. Этот аргумент принимает одно из следующих значений:
| Значение поведения | Описание |
|---|---|
legacy |
При возникновении собственного сбоя, Unity обворачивает и отправляет сбой как исключение Java. Unity не пересылает сбой ни к установленным обработчикам сбоев, ни к системе по умолчанию. Примечание: Это значение поведения не поддерживается GameActivity и будет удалено в будущих версиях Unity. |
disabled |
При возникновении собственного сбоя Unity игнорирует его, а Android пересылает сбой непосредственно следующему обработчику сбоев в цепи. Это либо пользовательский обработчик сбоев, если он установлен, либо система по умолчанию, если таковой не установлен. Примечание: Если вы используете это значение, службы Unity, такие как Unity Cloud Диагностика, больше не будут обрабатывать сбои и не будут сообщать о них. |
Сведения о передаче этого аргумента командной строки 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;
}
}
Установка обработчика сбоев
Чтобы установить crash handler и чтобы Unity использовал его для обработки сбоев, вызовите метод InstallCustomSignalHandlers в вышеуказанном файле cpp. Вы можете сделать это либо через C#, либо через Java код, однако лучше всего вызывать этот метод из Java, потому что сбой может произойти после инициализации Unity Player, но до выполнения вашего кода C#.
Следующий пример кода показывает, как вызвать InstallCustomSignalHandlers Чтобы добавить его в свой проект, вы можете либо установить файл Java в качестве плагина (см. Создание исходного плагина Java или Kotlin) или вы можете изменить существующий файл Java в экспортированный проект.
Примечание: В зависимости от того, где вы вызываете этот метод, он изменяет поведение обработки сбоев. Если вы вызываете его до Unity инициализации времени выполнения, которая представляет собой строку кода, содержащую mUnityPlayer = new UnityPlayer(this, this);, а затем во время собственной аварии UnityОбработчик сбоев ’s выполняется в первую очередь, а затем выполняется ваш обработчик сигналов (если Unity пересылает сигнал). Если вы звоните InstallCustomSignalHandlers после Unity инициализации runtime, а затем во время собственной аварии ваш обработчик выполняется первым, и это ваша ответственность передать сигнал.
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();
}
...