Use an obtained class loader instead of the default

This commit is contained in:
folecr 2013-07-19 15:01:42 -07:00
parent 669427363f
commit 53b1a92773
3 changed files with 104 additions and 66 deletions

View File

@ -29,9 +29,6 @@ THE SOFTWARE.
#define LOG_TAG "JniHelper" #define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) #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(); JavaVM* jvm = cocos2d::JniHelper::getJavaVM();
@ -74,25 +71,35 @@ extern "C"
} }
} }
jclass _getClassID(const char *className, JNIEnv *env) { jclass _getClassID(const char *className) {
if (NULL == className) { if (NULL == className) {
return NULL; return NULL;
} }
jclass ret = env->FindClass(className);
if (!ret) { jstring _jstrClassName = cocos2d::JniHelper::loadclassMethod.env->NewStringUTF(className);
LOGD("Failed to find class of %s", className);
} // explicit cast to jclass, since the returned object
jobject _clazzObject = cocos2d::JniHelper::loadclassMethod.env->CallObjectMethod(cocos2d::JniHelper::classloader,
return ret; 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 { namespace cocos2d {
JavaVM* JniHelper::_psJavaVM = NULL; JavaVM* JniHelper::_psJavaVM = NULL;
JniMethodInfo JniHelper::loadclassMethod = {NULL, NULL, NULL};
jobject JniHelper::classloader = NULL;
JavaVM* JniHelper::getJavaVM() { JavaVM* JniHelper::getJavaVM() {
pthread_t thisthread = pthread_self(); pthread_t thisthread = pthread_self();
@ -100,10 +107,37 @@ namespace cocos2d {
return _psJavaVM; return _psJavaVM;
} }
void JniHelper::setJavaVM(JavaVM *javaVM) { void JniHelper::setJavaVM(JavaVM *javaVM, jobject nativeActivityInstance) {
pthread_t thisthread = pthread_self(); pthread_t thisthread = pthread_self();
LOGD("JniHelper::setJavaVM(%p), pthread_self() = %X", javaVM, thisthread); LOGD("JniHelper::setJavaVM(%p), pthread_self() = %X", javaVM, thisthread);
_psJavaVM = javaVM; _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, bool JniHelper::getStaticMethodInfo(JniMethodInfo &methodinfo,
@ -122,7 +156,7 @@ namespace cocos2d {
return false; return false;
} }
jclass classID = _getClassID(className, pEnv); jclass classID = _getClassID(className);
if (! classID) { if (! classID) {
LOGD("Failed to find class %s", className); LOGD("Failed to find class %s", className);
return false; return false;
@ -155,7 +189,7 @@ namespace cocos2d {
return false; return false;
} }
jclass classID = _getClassID(className, pEnv); jclass classID = _getClassID(className);
if (! classID) { if (! classID) {
LOGD("Failed to find class %s", className); LOGD("Failed to find class %s", className);
return false; return false;

View File

@ -40,14 +40,26 @@ typedef struct JniMethodInfo_
class CC_DLL JniHelper class CC_DLL JniHelper
{ {
public: public:
static void setJavaVM(JavaVM *javaVM, jobject nativeActivitInstance);
static JavaVM* getJavaVM(); static JavaVM* getJavaVM();
static void setJavaVM(JavaVM *javaVM); static bool getStaticMethodInfo(JniMethodInfo &methodinfo,
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode); const char *className,
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode); 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 std::string jstring2string(jstring str);
static JniMethodInfo loadclassMethod;
static jobject classloader;
private: private:
static JavaVM *_psJavaVM; static JavaVM *_psJavaVM;
static bool setClassLoader(jobject nativeActivityInstance);
}; };
NS_CC_END NS_CC_END

View File

@ -56,21 +56,13 @@ struct engine {
#include "shaders/CCShaderCache.h" #include "shaders/CCShaderCache.h"
#include "textures/CCTextureCache.h" #include "textures/CCTextureCache.h"
extern "C" void cocos_android_app_init(void); void cocos_android_app_init(void);
typedef struct cocos_dimensions { typedef struct cocos_dimensions {
int w; int w;
int h; int h;
} cocos_dimensions; } 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) { static void cocos_init(cocos_dimensions d, AAssetManager* assetmanager) {
LOGI("cocos_init(...)"); LOGI("cocos_init(...)");
pthread_t thisthread = pthread_self(); 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); cocos_dimensions d = engine_init_display(engine);
if ((d.w > 0) && if ((d.w > 0) &&
(d.h > 0)) { (d.h > 0)) {
jnihelper_init(app->activity->vm); cocos2d::JniHelper::setJavaVM(app->activity->vm, app->activity->clazz);
cocos_init(d, app->activity->assetManager); cocos_init(d, app->activity->assetManager);
} }