Android: handle native exceptions in Java (#223)
parent
96f80d2c30
commit
a9cc034eaf
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue