| Index: libadblockplus-android/jni/Utils.cpp | 
| diff --git a/libadblockplus-android/jni/Utils.cpp b/libadblockplus-android/jni/Utils.cpp | 
| index 6c1b9274c417a4cfa8f93b37314d858bae94c188..a7b3e6fb481aadb68cc21ca17644b62e004fa589 100644 | 
| --- a/libadblockplus-android/jni/Utils.cpp | 
| +++ b/libadblockplus-android/jni/Utils.cpp | 
| @@ -19,6 +19,71 @@ | 
| #include "Utils.h" | 
| +// precached in JNI_OnLoad and released in JNI_OnUnload | 
| +JniGlobalReference<jclass>* arrayListClass; | 
| +jmethodID arrayListCtor; | 
| + | 
| +JniGlobalReference<jclass>* filterClass; | 
| +jmethodID filterCtor; | 
| + | 
| +JniGlobalReference<jclass>* subscriptionClass; | 
| +jmethodID subscriptionCtor; | 
| + | 
| +JniGlobalReference<jclass>* notificationClass; | 
| +jmethodID notificationCtor; | 
| + | 
| +JniGlobalReference<jclass>* exceptionClass; | 
| + | 
| +void JniUtils_OnLoad(JavaVM* vm, JNIEnv* env, void* reserved) | 
| +{ | 
| + arrayListClass = new JniGlobalReference<jclass>(env, env->FindClass("java/util/ArrayList")); | 
| + arrayListCtor = env->GetMethodID(arrayListClass->Get(), "<init>", "()V"); | 
| + | 
| + filterClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("Filter"))); | 
| + filterCtor = env->GetMethodID(filterClass->Get(), "<init>", "(J)V"); | 
| + | 
| + subscriptionClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("Subscription"))); | 
| + subscriptionCtor = env->GetMethodID(subscriptionClass->Get(), "<init>", "(J)V"); | 
| + | 
| + notificationClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("Notification"))); | 
| + notificationCtor = env->GetMethodID(notificationClass->Get(), "<init>", "(J)V"); | 
| + | 
| + exceptionClass = new JniGlobalReference<jclass>(env, env->FindClass(PKG("AdblockPlusException"))); | 
| +} | 
| + | 
| +void JniUtils_OnUnload(JavaVM* vm, JNIEnv* env, void* reserved) | 
| +{ | 
| + if (arrayListClass) | 
| + { | 
| + delete arrayListClass; | 
| + arrayListClass = NULL; | 
| + } | 
| + | 
| + if (filterClass) | 
| + { | 
| + delete filterClass; | 
| + filterClass = NULL; | 
| + } | 
| + | 
| + if (subscriptionClass) | 
| + { | 
| + delete subscriptionClass; | 
| + subscriptionClass = NULL; | 
| + } | 
| + | 
| + if (notificationClass) | 
| + { | 
| + delete notificationClass; | 
| + notificationClass = NULL; | 
| + } | 
| + | 
| + if (exceptionClass) | 
| + { | 
| + delete exceptionClass; | 
| + exceptionClass = NULL; | 
| + } | 
| +} | 
| + | 
| std::string JniJavaToStdString(JNIEnv* env, jstring str) | 
| { | 
| if (!str) | 
| @@ -35,23 +100,29 @@ std::string JniJavaToStdString(JNIEnv* env, jstring str) | 
| jobject NewJniArrayList(JNIEnv* env) | 
| { | 
| - JniLocalReference<jclass> clazz(env, env->FindClass("java/util/ArrayList")); | 
| - jmethodID ctor = env->GetMethodID(*clazz, "<init>", "()V"); | 
| - return env->NewObject(*clazz, ctor); | 
| + return env->NewObject(arrayListClass->Get(), arrayListCtor); | 
| } | 
| -void JniAddObjectToList(JNIEnv* env, jobject list, jobject value) | 
| +jmethodID JniGetAddToListMethod(JNIEnv* env, jobject list) | 
| { | 
| JniLocalReference<jclass> clazz(env, env->GetObjectClass(list)); | 
| - jmethodID add = env->GetMethodID(*clazz, "add", "(Ljava/lang/Object;)Z"); | 
| - env->CallBooleanMethod(list, add, value); | 
| + return env->GetMethodID(*clazz, "add", "(Ljava/lang/Object;)Z"); | 
| +} | 
| + | 
| +void JniAddObjectToList(JNIEnv* env, jobject list, jmethodID addMethod, jobject value) | 
| +{ | 
| + env->CallBooleanMethod(list, addMethod, value); | 
| +} | 
| + | 
| +void JniAddObjectToList(JNIEnv* env, jobject list, jobject value) | 
| +{ | 
| + jmethodID addMethod = JniGetAddToListMethod(env, list); | 
| + JniAddObjectToList(env, list, addMethod, value); | 
| } | 
| void JniThrowException(JNIEnv* env, const std::string& message) | 
| { | 
| - JniLocalReference<jclass> clazz(env, | 
| - env->FindClass(PKG("AdblockPlusException"))); | 
| - env->ThrowNew(*clazz, message.c_str()); | 
| + env->ThrowNew(exceptionClass->Get(), message.c_str()); | 
| } | 
| void JniThrowException(JNIEnv* env, const std::exception& e) | 
| @@ -88,37 +159,37 @@ JNIEnvAcquire::~JNIEnvAcquire() | 
| } | 
| template<typename T> | 
| -static jobject NewJniObject(JNIEnv* env, const T& value, const char* javaClass) | 
| +static jobject NewJniObject(JNIEnv* env, const T& value, jclass clazz, jmethodID ctor) | 
| { | 
| if (!value.get()) | 
| { | 
| return 0; | 
| } | 
| - JniLocalReference<jclass> clazz( | 
| - env, | 
| - env->FindClass(javaClass)); | 
| - jmethodID method = env->GetMethodID(*clazz, "<init>", "(J)V"); | 
| + return env->NewObject(clazz, ctor, JniPtrToLong(new T(value))); | 
| +} | 
| - return env->NewObject( | 
| - *clazz, | 
| - method, | 
| - JniPtrToLong(new T(value))); | 
| +template<typename T> | 
| +static jobject NewJniObject(JNIEnv* env, const T& value, const char* javaClass) | 
| +{ | 
| + JniLocalReference<jclass> clazz( env, env->FindClass(javaClass)); | 
| + jmethodID ctor = env->GetMethodID(*clazz, "<init>", "(J)V"); | 
| + return NewJniObject(env, value, *clazz, ctor); | 
| } | 
| jobject NewJniFilter(JNIEnv* env, const AdblockPlus::FilterPtr& filter) | 
| { | 
| - return NewJniObject(env, filter, PKG("Filter")); | 
| + return NewJniObject(env, filter, filterClass->Get(), filterCtor); | 
| } | 
| jobject NewJniSubscription(JNIEnv* env, | 
| const AdblockPlus::SubscriptionPtr& subscription) | 
| { | 
| - return NewJniObject(env, subscription, PKG("Subscription")); | 
| + return NewJniObject(env, subscription, subscriptionClass->Get(), subscriptionCtor); | 
| } | 
| jobject NewJniNotification(JNIEnv* env, | 
| const AdblockPlus::NotificationPtr& notification) | 
| { | 
| - return NewJniObject(env, notification, PKG("Notification")); | 
| + return NewJniObject(env, notification, notificationClass->Get(), notificationCtor); | 
| } |