1 // Copyright © 2021-present 650 Industries, Inc. (aka Expo) 2 3 #include "JavaReferencesCache.h" 4 5 namespace expo { 6 std::shared_ptr<JavaReferencesCache> JavaReferencesCache::instance() { 7 static std::shared_ptr<JavaReferencesCache> singleton{new JavaReferencesCache}; 8 return singleton; 9 } 10 11 void JavaReferencesCache::loadJClasses(JNIEnv *env) { 12 loadJClass(env, "java/lang/Double", { 13 {"<init>", "(D)V"} 14 }); 15 16 loadJClass(env, "java/lang/Boolean", { 17 {"<init>", "(Z)V"} 18 }); 19 20 loadJClass(env, "java/lang/Integer", { 21 {"<init>", "(I)V"} 22 }); 23 24 loadJClass(env, "java/lang/Float", { 25 {"<init>", "(F)V"} 26 }); 27 28 loadJClass(env, "com/facebook/react/bridge/PromiseImpl", { 29 {"<init>", "(Lcom/facebook/react/bridge/Callback;Lcom/facebook/react/bridge/Callback;)V"} 30 }); 31 32 loadJClass(env, "java/lang/Object", {}); 33 } 34 35 void JavaReferencesCache::loadJClass( 36 JNIEnv *env, 37 const std::string &name, 38 const std::vector<std::pair<std::string, std::string>> &methodsNames 39 ) { 40 // Note this clazz variable points to a leaked global reference. 41 // This is appropriate for classes that are never unloaded which is any class in an Android app. 42 auto clazz = (jclass) env->NewGlobalRef(env->FindClass(name.c_str())); 43 44 MethodHashMap methods; 45 methods.reserve(methodsNames.size()); 46 47 for (auto &method: methodsNames) { 48 methods.insert( 49 {method, env->GetMethodID(clazz, method.first.c_str(), method.second.c_str())} 50 ); 51 } 52 53 jClassRegistry.insert( 54 {name, CachedJClass(clazz, std::move(methods))} 55 ); 56 } 57 58 JavaReferencesCache::CachedJClass &JavaReferencesCache::getJClass( 59 const std::string &className 60 ) { 61 return jClassRegistry.at(className); 62 } 63 64 jmethodID JavaReferencesCache::CachedJClass::getMethod( 65 const std::string &name, 66 const std::string &signature 67 ) { 68 return methods.at({name, signature}); 69 } 70 71 JavaReferencesCache::CachedJClass::CachedJClass( 72 jclass clazz, 73 MethodHashMap methods 74 ) : clazz(clazz), methods(std::move(methods)) {} 75 } // namespace expo 76