Unity 6.3
0 онлайн 20 гостей 3 в системе
Вход

Обработка сбоев 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();
  }
...