Android: handle native exceptions in Java (#223)

master
Bektur 2021-11-08 16:19:58 +06:00 committed by GitHub
parent 96f80d2c30
commit a9cc034eaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 52 additions and 8 deletions

View File

@ -187,4 +187,8 @@ public class GameActivity extends NativeActivity {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(browserIntent);
}
public void finishGame(String exc) {
finish();
}
}

View File

@ -59,7 +59,14 @@ void sanity_check_fn(const char *assertion, const char *file,
debug_stacks_print_to(errorstream);
#ifdef __ANDROID__
std::string capture = "An engine assumption failed: \"" + std::string(assertion) +
"\" in file: " + std::string(file) + ":" + std::to_string(line) +
" (" + std::string(function) + ")";
throw std::runtime_error(capture);
#else
abort();
#endif
}
void fatal_error_fn(const char *msg, const char *file,
@ -72,11 +79,18 @@ void fatal_error_fn(const char *msg, const char *file,
errorstream << std::endl << "In thread " << std::hex
<< thr_get_current_thread_id() << ":" << std::endl;
errorstream << file << ":" << line << ": " << function
<< ": A fatal error occured: " << msg << std::endl;
<< ": A fatal error occurred: " << msg << std::endl;
debug_stacks_print_to(errorstream);
#ifdef __ANDROID__
std::string capture = "A fatal error occurred: \"" + std::string(msg) +
"\" in file: " + std::string(file) + ":" + std::to_string(line) +
" (" + std::string(function) + ")";
throw std::runtime_error(capture);
#else
abort();
#endif
}
/*
@ -352,4 +366,3 @@ void debug_set_exception_handler()
SetUnhandledExceptionFilter(Win32ExceptionHandler);
#endif
}

View File

@ -38,7 +38,6 @@ extern "C" void external_pause_game();
void android_main(android_app *app)
{
int retval = 0;
porting::app_global = app;
Thread::setName("Main");
@ -49,15 +48,15 @@ void android_main(android_app *app)
free(argv[0]);
} catch (std::exception &e) {
errorstream << "Uncaught exception in main thread: " << e.what() << std::endl;
retval = -1;
porting::finishGame(e.what());
} catch (...) {
errorstream << "Uncaught exception in main thread!" << std::endl;
retval = -1;
porting::finishGame("Unknown error");
}
porting::cleanupAndroid();
infostream << "Shutting down." << std::endl;
exit(retval);
exit(0);
}
/**
@ -232,7 +231,7 @@ void showInputDialog(const std::string &acceptButton, const std::string &hint,
void openURIAndroid(const std::string &url)
{
jmethodID url_open = jnienv->GetMethodID(nativeActivity, "openURI",
"(Ljava/lang/String;)V");
"(Ljava/lang/String;)V");
FATAL_ERROR_IF(url_open == nullptr,
"porting::openURIAndroid unable to find java openURI method");
jstring jurl = jnienv->NewStringUTF(url.c_str());
@ -336,7 +335,30 @@ float getDisplayDensity()
return value;
}
v2u32 getDisplaySize() {
v2u32 getDisplaySize()
{
return porting::getWindowSize();
}
void finishGame(const std::string &exc)
{
if (jnienv->ExceptionCheck())
jnienv->ExceptionClear();
jmethodID finishMe;
try {
finishMe = jnienv->GetMethodID(nativeActivity,
"finishGame", "(Ljava/lang/String;)V");
} catch (...) {
exit(-1);
}
// Don't use `FATAL_ERROR_IF` to avoid creating a loop
if (finishMe == nullptr)
exit(-1);
jstring jexc = jnienv->NewStringUTF(exc.c_str());
jnienv->CallVoidMethod(app_global->activity->clazz, finishMe, jexc);
}
}

View File

@ -86,4 +86,9 @@ std::string getInputDialogValue();
* notify java on game exit
*/
void notifyExitGame();
/**
* call Android function to finish
*/
void finishGame(const std::string &exc);
}