22#include < string>
33#include " androidlog.h"
44#include " bspatch.h"
5+ #include < thread>
56
67using namespace std ;
78
@@ -36,4 +37,55 @@ Java_com_example_cpp_1native_internal_PatchUtil_patchAPK(JNIEnv *env, jclass cla
3637 env->ReleaseStringUTFChars (old_apk_file, argv[1 ]);
3738 env->ReleaseStringUTFChars (new_apk_file, argv[2 ]);
3839 env->ReleaseStringUTFChars (patch_file, argv[3 ]);
39- }
40+ }
41+
42+ static JavaVM* gVm = nullptr ; // 全局保存,供子线程 attach
43+
44+ // so 被加载时会把 JavaVM 存下来
45+ JNIEXPORT jint JNICALL JNI_OnLoad (JavaVM* vm, void *) {
46+ gVm = vm;
47+ return JNI_VERSION_1_6 ;
48+ }
49+
50+ // 子线程里真正干活的函数
51+ void worker (JNIEnv* env, jobject gCallback ) {
52+ // 1. 模拟耗时 2 秒
53+ std::this_thread::sleep_for (std::chrono::seconds (2 ));
54+
55+ // 2. 找到接口类
56+ jclass clazz = env->GetObjectClass (gCallback );
57+ jmethodID onResult = env->GetMethodID (clazz,
58+ " onResult" ,
59+ " (Ljava/lang/String;)V" );
60+
61+ // 3. 拼结果
62+ jstring msg = env->NewStringUTF (" C++ 线程执行完毕" );
63+
64+ // 4. 回调 Java
65+ env->CallVoidMethod (gCallback , onResult, msg);
66+
67+ // 5. 清理局部引用
68+ env->DeleteLocalRef (msg);
69+ env->DeleteLocalRef (clazz);
70+ }
71+
72+ extern " C"
73+ JNIEXPORT void JNICALL
74+ Java_com_example_cpp_1native_internal_NativeHouse_doHeavyWorkAsync (JNIEnv *env, jobject thiz,
75+ jobject callback) {
76+ // 1. callback 是局部变量,跨线程必须提升为全局引用
77+ jobject gCallback = env->NewGlobalRef (callback);
78+ if (gCallback == nullptr ) return ;
79+ // 2. 起 C++ 线程
80+ std::thread ([gCallback ]() {
81+ JNIEnv* env = nullptr ;
82+ // 3. 子线程 attach
83+ if (gVm ->AttachCurrentThread (&env, nullptr ) != 0 ) return ;
84+ worker (env, gCallback ); // 真正干活
85+ // 4. 别忘了 detach,否则线程退出会崩
86+ gVm ->DetachCurrentThread ();
87+ // 5. 全局引用用完要释放
88+ env->DeleteGlobalRef (gCallback );
89+ }).detach ();
90+ }
91+
0 commit comments