Android JNI - 调用 AttachCurrentThread 而不使用 DetachCurrentThread

2024-01-07

我一直在阅读有关 JNI 的内容,似乎无法弄清楚如果线程启动 -> 调用 AttachCurrentThread() -> 进行一些 JNI 调用 -> 线程退出会发生什么。

理想情况下,我们应该在线程退出之前调用 DetachCurrentThread(),但是,如果应用程序不这样做会有什么影响?会导致内存泄漏或任何其他问题吗?


Not calling DetachCurrentThread() will definitely cause a memory leak; other consequences are JVM-specific, and probably irrelevant for Android apps, where the JVM shuts down when the process exits. There are quite a few C++ wrappers that help to manage thread Attach/Detach, see for example: http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier

Update:1000 感谢fadden https://stackoverflow.com/users/294248/fadden为了大开眼界link https://android.googlesource.com/platform/dalvik/+/kitkat-release/vm/Thread.cpp;在 Dalvik 上,一个不调用就退出的线程DetachCurrentThread(),导致整个虚拟机和进程崩溃。

这是来自官方模拟器的logcat,我的代码基于HelloJni https://android.googlesource.com/platform/development/+/master/ndk/samples/hello-jni来自 NDK 的示例:

10-26 04:16:25.853: D/dalvikvm(1554): Trying to load lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0
10-26 04:16:25.893: D/dalvikvm(1554): Added shared lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0
10-26 04:16:25.893: D/dalvikvm(1554): No JNI_OnLoad found in /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0, skipping init
10-26 04:16:26.463: D/gralloc_goldfish(1554): Emulator without GPU emulation detected.
10-26 04:16:31.033: D/threadFunction(1554): Attaching
10-26 04:16:31.173: D/threadFunction(1554): Not Detaching
10-26 04:16:31.183: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=0)
10-26 04:16:31.193: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=1)
10-26 04:16:31.193: E/dalvikvm(1554): threadid=11: native thread exited without detaching
10-26 04:16:31.193: E/dalvikvm(1554): VM aborting
10-26 04:16:31.213: A/libc(1554): Fatal signal 6 (SIGABRT) at 0x00000612 (code=-6), thread 1567 (xample.hellojni)

这是添加的相关功能hello-jni.c https://android.googlesource.com/platform/development/+/master/ndk/samples/hello-jni/jni/hello-jni.c:

static JavaVM* jvm = 0;
static jobject activity = 0; // GlobalRef

void* threadFunction(void* irrelevant)
{
    JNIEnv* env;
    usleep(5000000);

    __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Attaching");

    (*jvm)->AttachCurrentThread(jvm, &env, NULL);

    jclass clazz = (*env)->GetObjectClass(env, activity);
    jmethodID methodID = (*env)->GetMethodID(env, clazz, "finish", "()V" );
    (*env)->CallVoidMethod(env, activity, methodID);

    __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Not Detaching");
//    (*jvm)->DetachCurrentThread(jvm);
}

jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
    (*env)->GetJavaVM(env, &jvm);
    activity = (*env)->NewGlobalRef(env, thiz);

    pthread_t hThread;
    pthread_create(&hThread, NULL, &threadFunction, NULL);
    return (*env)->NewStringUTF(env, "Hello from JNI !");
}

WebRTC 中可以找到该策略的一个很好的实现git repo https://webrtc.googlesource.com/src/+/master/sdk/android/src/jni/jvm.cc#106.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android JNI - 调用 AttachCurrentThread 而不使用 DetachCurrentThread 的相关文章

  • 如何从android ble扫描结果中获取CRC?

    我每次都从 ble 设备收到 62 字节的扫描结果 使用下面的回调代码获取扫描结果 我可以获取 RSSI 但无法获取 CRC 或者 获取一帧的CRC的逻辑是什么 来自 ble 设备的数据格式 如数据包标头 广告数据 CRC RSSI 如何从
  • 模拟器中 Google Wear 上的语音识别器没有语音输入

    我试图使用 Google Wear 网站上的自由形式语音输入 在 hello world 示例中 我刚刚添加了对 textView 的单击 它确实从语音意图中调出 立即发言 活动 但模拟器无法检测到我的麦克风发出的任何声音 我使用的是 Ma
  • Android TelecomManager 中的 addIncomingCall 没有执行任何操作

    我正在尝试使用本机 Android 来电 UI 我有一个连接服务 并且我已经成功注册了一个电话帐户 但在我调用方法 addNewIncomingCall 后什么也没有发生 对我所缺少的有什么想法吗 显现
  • Android Camera.takePicture() 有时不返回?

    我正在编写一个Android 拍照应用程序 该代码在 onPreviewFrame byte data Cameracamera 中从预览中获取帧后进行一些处理 问题在于 android hardware Camera 的函数 takePi
  • 无法在 Android Studio 中导出签名的 APK

    当我使用keytool list keystore path to keyfile jks并提供我的密码 我可以看到那里的条目 但是当我在尝试使用相同的密码生成签名的 APK 时使用相同的密码时 我收到错误 无法加载密钥库 密钥库被篡改 或
  • 蓝牙 BLE Android 以最大吞吐量写入外设

    我们公司开发了一个具有蓝牙 BLE 的硬件单元 并且我们在 Nexus 7 2013 中有一个服务应用程序 我们希望使用它向该单元发送固件文件 文件最大可达 500kb BT芯片是德州仪器CC2540 我浏览了大量的页面 并扫描了 Stac
  • 自动删除 Firebase 通知

    我有一个问题 我都读过让通知在 5 分钟后消失 https stackoverflow com questions 15648699 make notification disappear after 5 minutes and 几秒钟后清
  • 如何清除Android剪贴板?

    我发现的方法都不起作用 这是我尝试过的 1 使用clearPrimaryClip 的方法ClipboardManager class ClipboardManager clipboard ClipboardManager getSystem
  • Android 和 Google 地图内部片段以及其他控件和 viewpager

    我是android编程新手 我有一个带有 3 个页面 片段 的小应用程序 使用 pageradapter 和 viewpager 在它们之间滑动 其中一个页面包含复选框 和其他控件 和地图 我的问题是程序在启动时崩溃 Fragment co
  • FragmentActivity 无法解析为类型

    我正在尝试来自的应用程序这个博客 http android developers blogspot com 2011 02 android 30 fragments api html 在延长的同时FragmentActivity 我收到以下
  • 如何在android中的谷歌地图上聚焦标记

    我只是想知道我们是否可以关注 Android 应用程序中添加的标记 如果是 怎么办 或者有没有其他方法可以完成这项任务 可以说我使用下面的代码添加了一个标记 map addMarker new MarkerOptions title tit
  • Android:WebView/BaseInputConnection 中的退格键

    我在 Android 4 2 中遇到软键盘退格问题 我在 WebView CodeMirror 中有一个自定义编辑器 它使用一个空的
  • Android 认为我没有关闭数据库!为什么?

    我有一个 SQLiteDatabase 数据成员 我在 onCreate 中初始化它 并在 onPause onStop 和 onDestroy 中调用 close 它在 onResume 中重新初始化 它似乎运行得很好 但当我查看调试器时
  • 如何将 JSON 数据从 Android 发送到 php url?

    我想将登录信息从我的应用程序发送到 php url 因为这我的应用程序将崩溃 任何人都可以帮助我解决这个问题 这是我的服务器登录方法 我想将数据发送到此登录方法 Method public method login Parameters 3
  • 通过 Gradle 和 Android Studio 构建和运行应用程序比通过 Eclipse 慢

    我有一个多项目 10 个模块 每次构建大约需要 20 30 秒 当我在 Android Studio 中按 运行 时 每次都必须等待才能重建应用程序 这非常慢 是否可以在 Android Studio 中自动化构建过程 或者您对如何加快此过
  • XML 配置中的 screenName 不起作用

    我刚刚在我的应用程序中添加了对 Google Analytics 分析 的支持 但我无法
  • 调试android数据绑定?

    谁能告诉我如何调试或找到数据绑定生成的代码 从this https www youtube com watch v NBbeQMOcnZ0链接我发现它生成了所需的代码 我猜您正在寻找自动生成的绑定 java 文件 我也在寻找他们 最后我在这
  • 在数组列表中过滤 Filterable 不取消之前的过滤

    我看过过滤器方法文档 其中显示调用过滤器会取消所有先前未执行的过滤请求 并发布一个稍后将执行的新过滤请求 但我收到的实际回调有些不同 在我的实现中 它不会取消先前的过滤器请求并调用publishResults 最近一次搜索条件后的上一次搜索
  • 如何从DataSource.Factory获取数据

    我必须调用此方法才能获取所有人员 我根本无法修改这个方法 Query SELECT FROM PERSON TABLE ORDER BY NAME DESC abstract fun getElements DataSource Facto
  • 如何用LoaderManager自动重新查询

    我有一个应用程序显示来自 SQLite DB 的数据 并且数据不断变化 所以显然 我认为我应该使用 LoaderManager 来显示数据 我读过一些关于将 LoaderManager 与 SQLite 结合使用的内容 然后看到了亚历克斯

随机推荐

  • MinGW 错误:“线程”不是“std”的成员

    我正在尝试为 Windows 交叉编译一个简单的应用程序 include
  • 为什么gmtime要这样实现呢?

    我偶然发现了 Minix 的 gmtime 函数的源代码 我对从纪元以来的天数计算年份数的位感兴趣 以下是该部分的内容 http www raspberryginger com jbailey minix html gmtime 8c so
  • 通过 COM 将 DataTable 传递到 R

    我试图将数据从 SQL 传递到 C 然后传递到 R 服务器进行数据分析 然后返回到我的 Web 应用程序 但是 我使用的 COM 接口不允许在 C 和 R 之间传递复杂的数据类型 无数据表 我过去使用以下代码让它工作 int count d
  • NSTask 阻塞主线程

    我正在使用 NSTask 但是当我启动任务时 它会阻塞主线程 因此我无法更新它 直到任务结束 这是我的代码 NSString hostsforping google es pingdata NSTask alloc init pingdat
  • 使用 ListFragment 填充自定义视图列表

    我正在尝试使用片段在列表视图中显示元素 我创建了自定义视图 如下所示 list row xml 的图形表示 列表行 xml
  • 如何恢复过期的令牌[AWS Cognito]?

    我的网站使用 AWS 1 小时后 令牌就会过期 用户几乎无法执行任何操作 现在我正在尝试像这样刷新凭据 function getTokens session return accessToken session getAccessToken
  • 身份服务器单点注销,也从服务器注销

    这是我在依赖方中使用的注销代码 FederationConfiguration cfg FederatedAuthentication FederationConfiguration var fam FederatedAuthenticat
  • 使用 Marionette.ItemView 获取没有模型的视图?

    是否常规使用Marionette ItemView对于没有特定的视图类model与他们相关的财产 As Marionette View并不意味着可以直接使用 它看起来像一个ItemView作为具有方便的默认值和绑定的视图类是有意义的 或者
  • PHP PDO Sqlsrv 始终以字符串形式返回每个值

    如何从具有正确字段类型的数据库中获取值 我使用 PDO Sqlsrv 从数据库获取数据 并且总是以字符串形式接收数据 如下所示 customer id 1 My customer id字段类型应该是整数customer id 1 But p
  • SQL Server:如何将所有行的数据作为 Json 对象查询到其他列旁边?

    I have data like this I want to query result like this 这是我的代码 SELECT PML CODE PML NAME ENG SELECT PML ID PML NO PML CODE
  • 签入/签出文件时 Sharepoint“不支持的段类型”

    我想使用OneDrive REST API 上的签出 签入功能 https learn microsoft com en us onedrive developer rest api api driveitem checkout https
  • 可以包含 javascript 的 HTML 属性

    我正在寻找一个包含所有 html 属性的简单列表 这些属性可以包含在执行操作时自动运行的 javascript 我知道这在浏览器和版本之间会有所不同 但我宁愿更安全 也不愿后悔 我目前知道以下 javascript 属性 onload on
  • 应用程序因内存问题而终止

    在我的应用程序中 我收到此错误 来自调试器的消息 由于内存问题而终止 并且应用程序崩溃 我正在显示一个网页 但问题是内存使用量不太高 应用程序使用的内存不到 100 MB 仅当我在 iPhone 6 Plus 中运行该应用程序时 该应用程序
  • 单个主机上的多个 glibc 库

    我的 Linux SLES 8 服务器当前有 glibc 2 2 5 235 但我有一个程序无法在此版本上运行并且需要 glibc 2 3 3 是否可以在同一主机上安装多个 glibc 这是我在旧 glibc 上运行程序时遇到的错误 mya
  • 使用 javascript 读取多个同时键盘输入

    我注意到 JavaScript 中键盘输入有一些奇怪的行为 我可能在这里遗漏了一些非常明显的东西 但是是否有某种关于允许同时按下哪些键的规则 我使用布尔变量来保存四个键中每个键的状态 如下所示 这允许同时按下许多键 硬件允许 var up
  • 恢复 Git 存储库中已删除的文件夹

    我已经删除了文件夹中的所有内容 并且该文件夹为空 我的远程仓库中仍然有一份副本 但是当我做了一个git pull它没有放回已删除的文件不是应该这样做吗 所以我做了一些研究 发现你可以通过执行以下操作来恢复文件git checkout
  • 一次读取每个字符 - C

    对于下面的question https users cs cf ac uk Dave Marshall C node7 html SECTION00730000000000000000 练习 12336 从程序的标准输入中一次读取一个字符的
  • 将整数转换为随机但确定性可重复的选择

    如何将无符号整数 表示用户 ID 转换为看起来随机但实际上是确定性可重复的选择 必须以相等的概率选择该选项 无论输入整数的分布如何 例如 如果我有 3 个选择 即 0 1 2 例如 用户ID 123可以总是被随机分配选择2 而用户ID 23
  • git 日志格式中可选的缩进换行符

    我一直在摆弄git一些的别名log命令 我已经拥有了大部分我想要的东西 信用在这里 https stackoverflow com a 9074343 241211 但我在一件事情上遇到了麻烦 当我打电话时 git log graph fo
  • Android JNI - 调用 AttachCurrentThread 而不使用 DetachCurrentThread

    我一直在阅读有关 JNI 的内容 似乎无法弄清楚如果线程启动 gt 调用 AttachCurrentThread gt 进行一些 JNI 调用 gt 线程退出会发生什么 理想情况下 我们应该在线程退出之前调用 DetachCurrentTh