mirror of
https://github.com/vcmi/vcmi.git
synced 2025-06-17 00:07:41 +02:00
Android support (#299)
* AI libs registering shenanigans on android; * Fixed resolution aspect + mouse event scaling; * Proper server init/deinit (through android IPC); Enabled threaded init in CMT; * Prevented a deadlock in logger on some devices; * Fixed frozen intro frame after interrupting the video; Added android progressbar displaying during initial data loading; * Hacky fix for choppy animations during heroes movement (should look better now, but it's definitely not a good solution); * Changes/fixes for new android launcher building process; * Fixed app hang after getting SDL_QUIT when activity was destroyed; * Functioanal, configurable advmap swiping support; * VCMI changes cleanup; Added few missing VCMI_ANDROID guards on swipe mechanics; * Removed unneeded sleep in server startup code for android; * Removed android ioapi hack (fixed in newest ndk); * Removed unused android's library loading logic; * Added android's swipe option to settings schema; * Moved NO_STD_TOSTRING to be defined in global.h instead of build files;
This commit is contained in:
105
lib/CAndroidVMHelper.cpp
Normal file
105
lib/CAndroidVMHelper.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* CAndroidVMHelper.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#include "CAndroidVMHelper.h"
|
||||
|
||||
static JavaVM * vmCache = nullptr;
|
||||
|
||||
/// cached java classloader so that we can find our classes from other threads
|
||||
static jobject vcmiClassLoader;
|
||||
static jmethodID vcmiFindClassMethod;
|
||||
|
||||
void CAndroidVMHelper::cacheVM(JNIEnv * env)
|
||||
{
|
||||
env->GetJavaVM(&vmCache);
|
||||
}
|
||||
|
||||
void CAndroidVMHelper::cacheVM(JavaVM * vm)
|
||||
{
|
||||
vmCache = vm;
|
||||
}
|
||||
|
||||
CAndroidVMHelper::CAndroidVMHelper()
|
||||
{
|
||||
auto res = vmCache->GetEnv((void **) &envPtr, JNI_VERSION_1_1);
|
||||
if(res == JNI_EDETACHED)
|
||||
{
|
||||
auto attachRes = vmCache->AttachCurrentThread(&envPtr, nullptr);
|
||||
if(attachRes == JNI_OK)
|
||||
{
|
||||
detachInDestructor = true; // only detach if we actually attached env
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
detachInDestructor = false;
|
||||
}
|
||||
}
|
||||
|
||||
CAndroidVMHelper::~CAndroidVMHelper()
|
||||
{
|
||||
if(envPtr && detachInDestructor)
|
||||
{
|
||||
vmCache->DetachCurrentThread();
|
||||
envPtr = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEnv * CAndroidVMHelper::get()
|
||||
{
|
||||
return envPtr;
|
||||
}
|
||||
|
||||
jclass CAndroidVMHelper::findClassloadedClass(const std::string & name)
|
||||
{
|
||||
auto env = get();
|
||||
return static_cast<jclass>(env->CallObjectMethod(vcmiClassLoader, vcmiFindClassMethod,
|
||||
env->NewStringUTF(name.c_str())));;
|
||||
}
|
||||
|
||||
void CAndroidVMHelper::callStaticVoidMethod(const std::string & cls, const std::string & method,
|
||||
bool classloaded /*=false*/)
|
||||
{
|
||||
auto env = get();
|
||||
auto javaHelper = findClass(cls, classloaded);
|
||||
auto methodId = env->GetStaticMethodID(javaHelper, method.c_str(), "()V");
|
||||
env->CallStaticVoidMethod(javaHelper, methodId);
|
||||
}
|
||||
|
||||
std::string CAndroidVMHelper::callStaticStringMethod(const std::string & cls, const std::string & method,
|
||||
bool classloaded /*=false*/)
|
||||
{
|
||||
auto env = get();
|
||||
auto javaHelper = findClass(cls, classloaded);
|
||||
auto methodId = env->GetStaticMethodID(javaHelper, method.c_str(), "()Ljava/lang/String;");
|
||||
jstring jres = static_cast<jstring>(env->CallStaticObjectMethod(javaHelper, methodId));
|
||||
return std::string(env->GetStringUTFChars(jres, nullptr));
|
||||
}
|
||||
|
||||
jclass CAndroidVMHelper::findClass(const std::string & name, bool classloaded)
|
||||
{
|
||||
if(classloaded)
|
||||
{
|
||||
return findClassloadedClass(name);
|
||||
}
|
||||
return get()->FindClass(name.c_str());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_initClassloader(JNIEnv * baseEnv, jobject * cls)
|
||||
{
|
||||
CAndroidVMHelper::cacheVM(baseEnv);
|
||||
CAndroidVMHelper envHelper;
|
||||
auto env = envHelper.get();
|
||||
auto anyVCMIClass = env->FindClass(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS);
|
||||
jclass classClass = env->GetObjectClass(anyVCMIClass);
|
||||
auto classLoaderClass = env->FindClass("java/lang/ClassLoader");
|
||||
auto getClassLoaderMethod = env->GetMethodID(classClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
|
||||
vcmiClassLoader = (jclass) env->NewGlobalRef(env->CallObjectMethod(anyVCMIClass, getClassLoaderMethod));
|
||||
vcmiFindClassMethod = env->GetMethodID(classLoaderClass, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");
|
||||
}
|
Reference in New Issue
Block a user