diff --git a/client/mainmenu/CMainMenu.cpp b/client/mainmenu/CMainMenu.cpp index 62341d224..09a674ccc 100644 --- a/client/mainmenu/CMainMenu.cpp +++ b/client/mainmenu/CMainMenu.cpp @@ -53,6 +53,10 @@ #include "../../lib/CondSh.h" #include "../../lib/mapping/CCampaignHandler.h" +#if defined(SINGLE_PROCESS_APP) && defined(VCMI_ANDROID) +#include "../../server/CVCMIServer.h" +#include +#endif namespace fs = boost::filesystem; @@ -459,7 +463,7 @@ CSimpleJoinScreen::CSimpleJoinScreen(bool host) if(host && !settings["session"]["donotstartserver"].Bool()) { textTitle->setText("Connecting..."); - boost::thread(&CSimpleJoinScreen::connectThread, this, "", 0); + startConnectThread(); } else { @@ -484,7 +488,7 @@ void CSimpleJoinScreen::connectToServer() buttonOk->block(true); GH.stopTextInput(); - boost::thread(&CSimpleJoinScreen::connectThread, this, inputAddress->getText(), boost::lexical_cast(inputPort->getText())); + startConnectThread(inputAddress->getText(), boost::lexical_cast(inputPort->getText())); } void CSimpleJoinScreen::leaveScreen() @@ -505,7 +509,18 @@ void CSimpleJoinScreen::onChange(const std::string & newText) buttonOk->block(inputAddress->getText().empty() || inputPort->getText().empty()); } -void CSimpleJoinScreen::connectThread(const std::string addr, const ui16 port) +void CSimpleJoinScreen::startConnectThread(const std::string & addr, ui16 port) +{ +#if defined(SINGLE_PROCESS_APP) && defined(VCMI_ANDROID) + // in single process build server must use same JNIEnv as client + // as server runs in a separate thread, it must not attempt to search for Java classes (and they're already cached anyway) + // https://github.com/libsdl-org/SDL/blob/main/docs/README-android.md#threads-and-the-java-vm + CVCMIServer::reuseClientJNIEnv(SDL_AndroidGetJNIEnv()); +#endif + boost::thread(&CSimpleJoinScreen::connectThread, this, addr, port); +} + +void CSimpleJoinScreen::connectThread(const std::string & addr, ui16 port) { setThreadName("CSimpleJoinScreen::connectThread"); if(!addr.length()) diff --git a/client/mainmenu/CMainMenu.h b/client/mainmenu/CMainMenu.h index 1a7fb5b6b..a3a8cbc44 100644 --- a/client/mainmenu/CMainMenu.h +++ b/client/mainmenu/CMainMenu.h @@ -167,7 +167,8 @@ class CSimpleJoinScreen : public WindowBase void connectToServer(); void leaveScreen(); void onChange(const std::string & newText); - void connectThread(const std::string addr = "", const ui16 inputPort = 0); + void startConnectThread(const std::string & addr = {}, ui16 port = 0); + void connectThread(const std::string & addr, ui16 port); public: CSimpleJoinScreen(bool host = true); diff --git a/lib/CAndroidVMHelper.cpp b/lib/CAndroidVMHelper.cpp index 59c690c21..2e3904ab2 100644 --- a/lib/CAndroidVMHelper.cpp +++ b/lib/CAndroidVMHelper.cpp @@ -18,6 +18,8 @@ static JavaVM * vmCache = nullptr; static jobject vcmiClassLoader; static jmethodID vcmiFindClassMethod; +bool CAndroidVMHelper::alwaysUseLoadedClass = false; + void CAndroidVMHelper::cacheVM(JNIEnv * env) { env->GetJavaVM(&vmCache); @@ -91,7 +93,7 @@ void CAndroidVMHelper::callCustomMethod(const std::string & cls, const std::stri jclass CAndroidVMHelper::findClass(const std::string & name, bool classloaded) { - if(classloaded) + if(alwaysUseLoadedClass || classloaded) { return findClassloadedClass(name); } diff --git a/lib/CAndroidVMHelper.h b/lib/CAndroidVMHelper.h index 625677e2d..748669458 100644 --- a/lib/CAndroidVMHelper.h +++ b/lib/CAndroidVMHelper.h @@ -46,6 +46,8 @@ public: static void initClassloader(void * baseEnv); + static bool alwaysUseLoadedClass; + static constexpr const char * NATIVE_METHODS_DEFAULT_CLASS = "eu/vcmi/vcmi/NativeMethods"; }; diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index b75a2cfff..4d01e5f9f 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -1191,4 +1191,12 @@ void CVCMIServer::create(boost::condition_variable * cond, const std::vector(&*argv.begin())); } -#endif + +#ifdef VCMI_ANDROID +void CVCMIServer::reuseClientJNIEnv(void * jniEnv) +{ + CAndroidVMHelper::initClassloader(jniEnv); + CAndroidVMHelper::alwaysUseLoadedClass = true; +} +#endif // VCMI_ANDROID +#endif // VCMI_ANDROID_DUAL_PROCESS diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index 35e1a5122..f5a0486ce 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -121,5 +121,8 @@ public: static void create(); #elif defined(SINGLE_PROCESS_APP) static void create(boost::condition_variable * cond, const std::vector & args); -#endif +# ifdef VCMI_ANDROID + static void reuseClientJNIEnv(void * jniEnv); +# endif // VCMI_ANDROID +#endif // VCMI_ANDROID_DUAL_PROCESS };