diff --git a/jni/NativeFormats/util/AndroidUtil.cpp b/jni/NativeFormats/util/AndroidUtil.cpp index e38a0c90b..8651e6792 100644 --- a/jni/NativeFormats/util/AndroidUtil.cpp +++ b/jni/NativeFormats/util/AndroidUtil.cpp @@ -25,7 +25,7 @@ JavaVM *AndroidUtil::ourJavaVM = 0; -const char * const AndroidUtil::Class_java_lang_String = "java/lang/String"; +shared_ptr AndroidUtil::Class_java_lang_String; const char * const AndroidUtil::Class_java_util_Collection = "java/util/Collection"; const char * const AndroidUtil::Class_java_util_Locale = "java/util/Locale"; const char * const AndroidUtil::Class_java_io_InputStream = "java/io/InputStream"; @@ -124,10 +124,9 @@ bool AndroidUtil::init(JavaVM* jvm) { JNIEnv *env = getEnv(); jclass cls; - CHECK_NULL( cls = env->FindClass(Class_java_lang_String) ); - Method_java_lang_String_toLowerCase = new StringMethod(env, cls, "toLowerCase", "()"); - Method_java_lang_String_toUpperCase = new StringMethod(env, cls, "toUpperCase", "()"); - env->DeleteLocalRef(cls); + Class_java_lang_String = new JavaClass(env, "java/lang/String"); + Method_java_lang_String_toLowerCase = new StringMethod(*Class_java_lang_String, "toLowerCase", "()"); + Method_java_lang_String_toUpperCase = new StringMethod(*Class_java_lang_String, "toUpperCase", "()"); CHECK_NULL( cls = env->FindClass(Class_java_util_Collection) ); CHECK_NULL( MID_java_util_Collection_toArray = env->GetMethodID(cls, "toArray", "()[Ljava/lang/Object;") ); @@ -313,8 +312,7 @@ jbyteArray AndroidUtil::createJavaByteArray(JNIEnv *env, const std::vector &data) { size_t size = data.size(); - jclass cls = env->FindClass("java/lang/String"); - jobjectArray array = env->NewObjectArray(size, cls, 0); + jobjectArray array = env->NewObjectArray(size, Class_java_lang_String->j(), 0); for (size_t i = 0; i < size; ++i) { const std::string &str = data[i]; if (str.length() > 0) { @@ -323,7 +321,6 @@ jobjectArray AndroidUtil::createJavaStringArray(JNIEnv *env, const std::vectorDeleteLocalRef(javaStr); } } - env->DeleteLocalRef(cls); return array; } diff --git a/jni/NativeFormats/util/AndroidUtil.h b/jni/NativeFormats/util/AndroidUtil.h index 391967227..79fff5a19 100644 --- a/jni/NativeFormats/util/AndroidUtil.h +++ b/jni/NativeFormats/util/AndroidUtil.h @@ -27,6 +27,7 @@ #include +class JavaClass; class VoidMethod; class IntMethod; class LongMethod; @@ -44,7 +45,7 @@ private: static JavaVM *ourJavaVM; public: - static const char * const Class_java_lang_String; + static shared_ptr Class_java_lang_String; static const char * const Class_java_util_Collection; static const char * const Class_java_util_Locale; static const char * const Class_java_io_InputStream; diff --git a/jni/NativeFormats/util/JniEnvelope.cpp b/jni/NativeFormats/util/JniEnvelope.cpp index 2d7daf718..1d4e03320 100644 --- a/jni/NativeFormats/util/JniEnvelope.cpp +++ b/jni/NativeFormats/util/JniEnvelope.cpp @@ -23,12 +23,28 @@ static const std::string JNI_LOGGER_CLASS = "JniLog"; +JavaClass::JavaClass(JNIEnv *env, const std::string &name) : myName(name), myEnv(env) { + jclass ref = env->FindClass(name.c_str()); + myClass = (jclass)env->NewGlobalRef(ref); + env->DeleteLocalRef(ref); +} + +JavaClass::~JavaClass() { + myEnv->DeleteGlobalRef(myClass); +} + Method::Method(JNIEnv *env, jclass cls, const std::string &name, const std::string &signature) : myName(name) { //ZLLogger::Instance().registerClass(JNI_LOGGER_CLASS); myEnv = env; myId = env->GetMethodID(cls, name.c_str(), signature.c_str()); } +Method::Method(const JavaClass &cls, const std::string &name, const std::string &signature) : myName(name) { + //ZLLogger::Instance().registerClass(JNI_LOGGER_CLASS); + myEnv = cls.myEnv; + myId = myEnv->GetMethodID(cls.myClass, name.c_str(), signature.c_str()); +} + Method::~Method() { } @@ -95,6 +111,9 @@ jboolean BooleanMethod::call(jobject base, ...) { StringMethod::StringMethod(JNIEnv *env, jclass cls, const std::string &name, const std::string &signature) : Method(env, cls, name, signature + "Ljava/lang/String;") { } +StringMethod::StringMethod(const JavaClass &cls, const std::string &name, const std::string &signature) : Method(cls, name, signature + "Ljava/lang/String;") { +} + jstring StringMethod::call(jobject base, ...) { ZLLogger::Instance().println(JNI_LOGGER_CLASS, "calling StringMethod " + myName); va_list lst; diff --git a/jni/NativeFormats/util/JniEnvelope.h b/jni/NativeFormats/util/JniEnvelope.h index 41492a057..16fbe0c5e 100644 --- a/jni/NativeFormats/util/JniEnvelope.h +++ b/jni/NativeFormats/util/JniEnvelope.h @@ -24,12 +24,37 @@ #include +class JavaClass { + +public: + JavaClass(JNIEnv *env, const std::string &name); + ~JavaClass(); + jclass j(); + +private: + JavaClass(const JavaClass&); + const JavaClass &operator = (const JavaClass&); + +private: + const std::string myName; + JNIEnv *myEnv; + jclass myClass; + +friend class Method; +friend class StaticMethod; +}; + class Method { public: Method(JNIEnv *env, jclass cls, const std::string &name, const std::string &signature); + Method(const JavaClass &cls, const std::string &name, const std::string &signature); virtual ~Method(); +private: + Method(const Method&); + const Method &operator = (const Method&); + protected: const std::string myName; JNIEnv *myEnv; @@ -42,6 +67,10 @@ public: StaticMethod(JNIEnv *env, jclass cls, const std::string &name, const std::string &signature); virtual ~StaticMethod(); +private: + StaticMethod(const StaticMethod&); + const StaticMethod &operator = (const StaticMethod&); + protected: const std::string myName; JNIEnv *myEnv; @@ -79,6 +108,7 @@ public: class StringMethod : public Method { public: + StringMethod(const JavaClass &cls, const std::string &name, const std::string &signature); StringMethod(JNIEnv *env, jclass cls, const std::string &name, const std::string &signature); jstring call(jobject base, ...); }; @@ -97,4 +127,6 @@ public: jobject call(jclass cls, ...); }; +inline jclass JavaClass::j() { return myClass; } + #endif /* __JNIENVELOPE_H__ */