Android 14中在std::thread内访问网络致应用崩溃求助
问题原因与解决方案
核心原因
崩溃的直接原因是你创建的std::thread对象在JNI函数返回时被销毁,但线程仍处于**可连接(joinable)**状态。根据C++标准,当std::thread的析构函数执行时,如果线程还未调用join()或detach(),会触发std::terminate(),最终调用abort()产生SIGABRT信号(对应日志里的Fatal signal 6)。
你的JNI函数stringFromJNI执行完毕返回时,栈上的t对象会被销毁,此时它内部的子线程还在执行gethostbyname,触发了上述的终止逻辑。而你第二个测试代码没有创建额外线程,直接在当前JNI线程执行网络调用,不存在线程对象析构的问题,所以运行正常。
解决方案
有两种方式修复这个问题:
1. 等待子线程完成(join)
修改Native代码,在返回前调用t.join(),确保子线程执行完毕再销毁线程对象:
extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; std::thread t{[&]{ gethostbyname("www.google.com"); }}; t.join(); // 等待子线程执行完成 return env->NewStringUTF(hello.c_str()); }
这种方式会阻塞当前JNI所在的Java线程,直到网络调用完成,适合不需要异步执行的场景。
2. 分离线程(detach)
如果需要子线程后台异步执行,调用t.detach()将线程与对象分离,这样线程对象销毁时不会影响后台线程的运行:
extern "C" JNIEXPORT jstring JNICALL Java_com_example_myapplication_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++"; std::thread t{[&]{ gethostbyname("www.google.com"); }}; t.detach(); // 分离线程,后台执行 return env->NewStringUTF(hello.c_str()); }
注意:分离后无法再通过线程对象控制或等待该线程,需要自行管理线程内的资源,避免内存泄漏或野指针问题。
额外说明
Android 14的网络权限或线程机制不是导致本次崩溃的原因,你已经声明了INTERNET权限,且Java线程调用网络正常,问题完全源于C++线程对象的生命周期管理。
内容的提问来源于stack exchange,提问作者larry
相关产品推荐
相关产品推荐

