mirror of https://github.com/axmolengine/axmol.git
Use an obtained class loader instead of the default
This commit is contained in:
parent
669427363f
commit
53b1a92773
|
@ -29,70 +29,77 @@ THE SOFTWARE.
|
|||
#define LOG_TAG "JniHelper"
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
|
||||
|
||||
extern "C"
|
||||
{
|
||||
static JNIEnv* _getJNIEnv(void) {
|
||||
|
||||
static JNIEnv* _getJNIEnv(void) {
|
||||
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
|
||||
if (NULL == jvm) {
|
||||
LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
|
||||
if (NULL == jvm) {
|
||||
LOGD("Failed to get JNIEnv. JniHelper::getJavaVM() is NULL");
|
||||
return NULL;
|
||||
}
|
||||
JNIEnv *env = NULL;
|
||||
// get jni environment
|
||||
jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4);
|
||||
|
||||
JNIEnv *env = NULL;
|
||||
// get jni environment
|
||||
jint ret = jvm->GetEnv((void**)&env, JNI_VERSION_1_4);
|
||||
switch (ret) {
|
||||
case JNI_OK :
|
||||
// Success!
|
||||
return env;
|
||||
|
||||
switch (ret) {
|
||||
case JNI_OK :
|
||||
// Success!
|
||||
case JNI_EDETACHED :
|
||||
// Thread not attached
|
||||
|
||||
// TODO : If calling AttachCurrentThread() on a native thread
|
||||
// must call DetachCurrentThread() in future.
|
||||
// see: http://developer.android.com/guide/practices/design/jni.html
|
||||
|
||||
if (jvm->AttachCurrentThread(&env, NULL) < 0)
|
||||
{
|
||||
LOGD("Failed to get the environment using AttachCurrentThread()");
|
||||
return NULL;
|
||||
} else {
|
||||
// Success : Attached and obtained JNIEnv!
|
||||
return env;
|
||||
|
||||
case JNI_EDETACHED :
|
||||
// Thread not attached
|
||||
|
||||
// TODO : If calling AttachCurrentThread() on a native thread
|
||||
// must call DetachCurrentThread() in future.
|
||||
// see: http://developer.android.com/guide/practices/design/jni.html
|
||||
|
||||
if (jvm->AttachCurrentThread(&env, NULL) < 0)
|
||||
{
|
||||
LOGD("Failed to get the environment using AttachCurrentThread()");
|
||||
return NULL;
|
||||
} else {
|
||||
// Success : Attached and obtained JNIEnv!
|
||||
return env;
|
||||
}
|
||||
|
||||
case JNI_EVERSION :
|
||||
// Cannot recover from this error
|
||||
LOGD("JNI interface version 1.4 not supported");
|
||||
default :
|
||||
LOGD("Failed to get the environment using GetEnv()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
case JNI_EVERSION :
|
||||
// Cannot recover from this error
|
||||
LOGD("JNI interface version 1.4 not supported");
|
||||
default :
|
||||
LOGD("Failed to get the environment using GetEnv()");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
jclass _getClassID(const char *className, JNIEnv *env) {
|
||||
if (NULL == className) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jclass ret = env->FindClass(className);
|
||||
if (!ret) {
|
||||
LOGD("Failed to find class of %s", className);
|
||||
}
|
||||
|
||||
return ret;
|
||||
jclass _getClassID(const char *className) {
|
||||
if (NULL == className) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
jstring _jstrClassName = cocos2d::JniHelper::loadclassMethod.env->NewStringUTF(className);
|
||||
|
||||
// explicit cast to jclass, since the returned object
|
||||
jobject _clazzObject = cocos2d::JniHelper::loadclassMethod.env->CallObjectMethod(cocos2d::JniHelper::classloader,
|
||||
cocos2d::JniHelper::loadclassMethod.methodID,
|
||||
_jstrClassName);
|
||||
|
||||
jclass _clazz = cocos2d::JniHelper::loadclassMethod.env->GetObjectClass(_clazzObject);
|
||||
|
||||
if (NULL == _clazz) {
|
||||
LOGD("Classloader failed to find class of %s", className);
|
||||
}
|
||||
|
||||
cocos2d::JniHelper::loadclassMethod.env->DeleteLocalRef(_jstrClassName);
|
||||
|
||||
return _clazz;
|
||||
}
|
||||
|
||||
namespace cocos2d {
|
||||
|
||||
JavaVM* JniHelper::_psJavaVM = NULL;
|
||||
JniMethodInfo JniHelper::loadclassMethod = {NULL, NULL, NULL};
|
||||
jobject JniHelper::classloader = NULL;
|
||||
|
||||
JavaVM* JniHelper::getJavaVM() {
|
||||
pthread_t thisthread = pthread_self();
|
||||
|
@ -100,10 +107,37 @@ namespace cocos2d {
|
|||
return _psJavaVM;
|
||||
}
|
||||
|
||||
void JniHelper::setJavaVM(JavaVM *javaVM) {
|
||||
void JniHelper::setJavaVM(JavaVM *javaVM, jobject nativeActivityInstance) {
|
||||
pthread_t thisthread = pthread_self();
|
||||
LOGD("JniHelper::setJavaVM(%p), pthread_self() = %X", javaVM, thisthread);
|
||||
_psJavaVM = javaVM;
|
||||
|
||||
if (!setClassLoader(nativeActivityInstance)) {
|
||||
LOGD("FAIL FAIL FAIL! Could not obtain Java class loader for application code");
|
||||
}
|
||||
}
|
||||
|
||||
bool JniHelper::setClassLoader(jobject nativeactivityinstance) {
|
||||
JniMethodInfo _getclassloaderMethod;
|
||||
if (!JniHelper::getMethodInfo(_getclassloaderMethod,
|
||||
"android/app/NativeActivity",
|
||||
"getClassLoader",
|
||||
"()Ljava/lang/ClassLoader;")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
jobject _c = _getclassloaderMethod.env->CallObjectMethod(nativeactivityinstance,
|
||||
_getclassloaderMethod.methodID);
|
||||
JniMethodInfo _m;
|
||||
if (!JniHelper::getMethodInfo(_m,
|
||||
"java/lang/ClassLoader",
|
||||
"loadClass",
|
||||
"(Ljava/lang/String;)Ljava/lang/Class;")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JniHelper::classloader = _c;
|
||||
JniHelper::loadclassMethod = _m;
|
||||
}
|
||||
|
||||
bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo,
|
||||
|
@ -122,7 +156,7 @@ namespace cocos2d {
|
|||
return false;
|
||||
}
|
||||
|
||||
jclass classID = _getClassID(className, pEnv);
|
||||
jclass classID = _getClassID(className);
|
||||
if (! classID) {
|
||||
LOGD("Failed to find class %s", className);
|
||||
return false;
|
||||
|
@ -155,7 +189,7 @@ namespace cocos2d {
|
|||
return false;
|
||||
}
|
||||
|
||||
jclass classID = _getClassID(className, pEnv);
|
||||
jclass classID = _getClassID(className);
|
||||
if (! classID) {
|
||||
LOGD("Failed to find class %s", className);
|
||||
return false;
|
||||
|
|
|
@ -40,14 +40,26 @@ typedef struct JniMethodInfo_
|
|||
class CC_DLL JniHelper
|
||||
{
|
||||
public:
|
||||
static void setJavaVM(JavaVM *javaVM, jobject nativeActivitInstance);
|
||||
static JavaVM* getJavaVM();
|
||||
static void setJavaVM(JavaVM *javaVM);
|
||||
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
|
||||
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
|
||||
static bool getStaticMethodInfo(JniMethodInfo &methodinfo,
|
||||
const char *className,
|
||||
const char *methodName,
|
||||
const char *paramCode);
|
||||
static bool getMethodInfo(JniMethodInfo &methodinfo,
|
||||
const char *className,
|
||||
const char *methodName,
|
||||
const char *paramCode);
|
||||
|
||||
static std::string jstring2string(jstring str);
|
||||
|
||||
static JniMethodInfo loadclassMethod;
|
||||
static jobject classloader;
|
||||
|
||||
private:
|
||||
static JavaVM *_psJavaVM;
|
||||
|
||||
static bool setClassLoader(jobject nativeActivityInstance);
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -56,21 +56,13 @@ struct engine {
|
|||
#include "shaders/CCShaderCache.h"
|
||||
#include "textures/CCTextureCache.h"
|
||||
|
||||
extern "C" void cocos_android_app_init(void);
|
||||
void cocos_android_app_init(void);
|
||||
|
||||
typedef struct cocos_dimensions {
|
||||
int w;
|
||||
int h;
|
||||
} cocos_dimensions;
|
||||
|
||||
static void jnihelper_init(JavaVM* vm) {
|
||||
LOGI("jnihelper_init(...)");
|
||||
pthread_t thisthread = pthread_self();
|
||||
LOGI("pthread_self() = %X", thisthread);
|
||||
|
||||
cocos2d::JniHelper::setJavaVM(vm);
|
||||
}
|
||||
|
||||
static void cocos_init(cocos_dimensions d, AAssetManager* assetmanager) {
|
||||
LOGI("cocos_init(...)");
|
||||
pthread_t thisthread = pthread_self();
|
||||
|
@ -259,7 +251,7 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
|
|||
cocos_dimensions d = engine_init_display(engine);
|
||||
if ((d.w > 0) &&
|
||||
(d.h > 0)) {
|
||||
jnihelper_init(app->activity->vm);
|
||||
cocos2d::JniHelper::setJavaVM(app->activity->vm, app->activity->clazz);
|
||||
cocos_init(d, app->activity->assetManager);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue