77#include < fbjni/detail/Registration.h>
88#include < typeinfo>
99#include " react-native-sync-tasks.hpp"
10+ #include " helpers/FetchService.hpp"
1011
1112
1213using namespace facebook ;
1314
15+ JavaVM* g_vm = nullptr ;
16+ jobject g_classLoader = nullptr ;
17+ jmethodID g_loadClass = nullptr ;
18+
19+ JNIEnv* getJNIEnv () {
20+ JNIEnv* env = nullptr ;
21+ if (g_vm->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
22+ // Поток не прикреплён — нужно attach
23+ g_vm->AttachCurrentThread (&env, nullptr );
24+ }
25+ return env;
26+ }
27+
28+ extern " C"
29+ JNIEXPORT void JNICALL
30+ Java_com_synctasks_SyncTasksModule_nativeSetClassLoader (JNIEnv* env, jclass, jobject classLoader) {
31+ g_classLoader = env->NewGlobalRef (classLoader);
32+ jclass classLoaderClass = env->FindClass (" java/lang/ClassLoader" );
33+ g_loadClass = env->GetMethodID (classLoaderClass, " loadClass" , " (Ljava/lang/String;)Ljava/lang/Class;" );
34+ }
35+
36+ void setupClassLoader (JNIEnv* env) {
37+ jclass contextClass = env->FindClass (" com/synctasks/SyncTasksModule" );
38+ jclass classClass = env->FindClass (" java/lang/Class" );
39+ jmethodID getClassLoader = env->GetMethodID (classClass, " getClassLoader" , " ()Ljava/lang/ClassLoader;" );
40+ jobject classLoader = env->CallObjectMethod (contextClass, getClassLoader);
41+ g_classLoader = env->NewGlobalRef (classLoader);
42+
43+ jclass classLoaderClass = env->FindClass (" java/lang/ClassLoader" );
44+ g_loadClass = env->GetMethodID (classLoaderClass, " loadClass" , " (Ljava/lang/String;)Ljava/lang/Class;" );
45+ }
46+
47+ jclass findClassSafe (JNIEnv* env, const char * name) {
48+ if (!g_classLoader || !g_loadClass) {
49+ __android_log_print (ANDROID_LOG_ERROR, " SYNC_TASKS" , " ClassLoader not initialized" );
50+ return nullptr ;
51+ }
52+ jstring strClassName = env->NewStringUTF (name);
53+ jclass clazz = (jclass)env->CallObjectMethod (g_classLoader, g_loadClass, strClassName);
54+ env->DeleteLocalRef (strClassName);
55+
56+ if (env->ExceptionCheck ()) {
57+ env->ExceptionDescribe ();
58+ env->ExceptionClear ();
59+ return nullptr ;
60+ }
61+ return clazz;
62+ }
63+
1464struct SyncTasksBridge : jni::JavaClass<SyncTasksBridge> {
1565public:
1666 static constexpr auto kJavaDescriptor = " Lcom/synctasks/SyncTasksModule;" ;
@@ -29,14 +79,70 @@ struct SyncTasksBridge : jni::JavaClass<SyncTasksBridge> {
2979 auto jsiRuntime = reinterpret_cast <jsi::Runtime*>(jsiRuntimePointer);
3080 auto jsCallInvoker = jsCallInvokerHolder->cthis ()->getCallInvoker ();
3181
82+ auto fetch = [](std::string&& url, FetchHeaders&& headers) -> FetchResponse {
83+ JNIEnv* env = getJNIEnv ();
84+
85+ jclass fetcherClass = findClassSafe (env, " com.synctasks.Fetcher" );
86+ if (!fetcherClass) {
87+ return FetchError{" Fetcher class not found" , " " , 0 };
88+ }
3289
33- sh::synctasks::install (jsiRuntime, jsCallInvoker);
90+ jmethodID fetchMethod = env->GetStaticMethodID (fetcherClass, " fetch" , " (Ljava/lang/String;Ljava/util/Map;)Ljava/lang/String;" );
91+ if (!fetchMethod) {
92+ return FetchError{" Fetcher.fetch() not found" , " " , 0 };
93+ }
3494
35- // Установите JSI
36- // sqldb::install(jsiRuntime, jsCallInvoker, dbPathStr);
95+ jstring jUrl = env->NewStringUTF (url.c_str ());
96+
97+ jclass mapClass = env->FindClass (" java/util/HashMap" );
98+ jmethodID init = env->GetMethodID (mapClass, " <init>" , " ()V" );
99+ jobject jMap = env->NewObject (mapClass, init);
100+
101+ jmethodID put = env->GetMethodID (mapClass, " put" , " (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;" );
102+
103+ for (const auto & [k, v] : headers) {
104+ jstring jk = env->NewStringUTF (k.c_str ());
105+ jstring jv = env->NewStringUTF (v.c_str ());
106+ env->CallObjectMethod (jMap, put, jk, jv);
107+ env->DeleteLocalRef (jk);
108+ env->DeleteLocalRef (jv);
109+ }
110+
111+ jstring jResult = (jstring)env->CallStaticObjectMethod (fetcherClass, fetchMethod, jUrl, jMap);
112+
113+ // jclass pairClass = env->FindClass("kotlin/Pair");
114+ // jmethodID getFirst = env->GetMethodID(pairClass, "getFirst", "()Ljava/lang/Object;");
115+ // jmethodID getSecond = env->GetMethodID(pairClass, "getSecond", "()Ljava/lang/Object;");
116+
117+
118+ // jobject jCodeObj = env->CallObjectMethod(resultPair, getFirst);
119+ // jobject jBodyObj = env->CallObjectMethod(resultPair, getSecond);
120+
121+ // const char* cstr = env->GetStringUTFChars(jResult, nullptr);
122+ // std::string body(cstr);
123+ // env->ReleaseStringUTFChars(jResult, cstr);
124+ //
125+ // env->DeleteLocalRef(jUrl);
126+ // env->DeleteLocalRef(jMap);
127+ // env->DeleteLocalRef(jResult);
128+ // env->DeleteLocalRef(fetcherClass);
129+
130+ return FetchBody (" " );
131+ };
132+
133+ sh::synctasks::install (jsiRuntime, jsCallInvoker,std::move (fetch));
37134 }
38135};
39136
40137JNIEXPORT jint JNI_OnLoad (JavaVM *vm, void *) {
138+ g_vm = vm;
139+
140+ JNIEnv* env = nullptr ;
141+ if (vm->GetEnv (reinterpret_cast <void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
142+ return JNI_ERR;
143+ }
144+
145+ setupClassLoader (env);
146+
41147 return jni::initialize (vm, [] { SyncTasksBridge::registerNatives (); });
42148}
0 commit comments