android - 用于后台服务的 Android O 和线程本地存储
问题描述
我在 android 上有一个使用后台服务 (startService) 的 VOIP 应用程序。后台服务负责 C/C++ 堆栈的创建和生命周期管理。自 Android O 以来,我在访问线程本地存储时看到崩溃:
#00 pc 000000000004bba8 /system/lib/libc.so (tgkill+12)
#01 pc 000000000001aa13 /system/lib/libc.so (abort+54)
#02 pc 000000000001f2f9 /system/lib/libc.so (__libc_fatal+24)
#03 pc 000000000001aedd /system/lib/libc.so (__assert2+16)
#04 pc 00000000000808ed /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_thread_this+36)
#05 pc 000000000007ffb3 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_log+610)
#06 pc 0000000000080215 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_log_5+24)
#07 pc 0000000000087941 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_timer_heap_destroy+28)
#08 pc 000000000007ad89 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libpjsip.so (pj_dns_resolver_destroy+232)
#09 pc 00000000000dd418 /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libMyApp.so
#10 pc 00000000000dd69c /data/app/com.myapp.system-TqIMuM73wCvczia_yKDs4g==/lib/arm/libMyApp.so
我正在使用 PJSIP 库,它需要在使用之前注册线程,如果没有,它会因断言而失败。它在内部使用线程本地存储来管理注册(基于 pthread_getspecific、pthread_setspecific)。
我已经注册了所有可能访问 pjsip API 的线程,尤其是:pj_dns_resolver_destroy。但是线程本地存储仍然认为线程没有注册。这仅在 Android 8.0+ 上发生。
这让我想到是否有可能触发此行为的 Android O 更改。
更多背景:
1) pj_dns_resolver_destroy 可以在两种情况下调用:网络变化和应用程序关闭,即后台服务停止。
2) 我使用基于 BroadcastReceiver 的网络监控来传递可以调用 pj_dns_resolver_destroy 的网络更改事件。
附加信息:
服务生命周期以有序的方式处理。PJSIP 提供 pj_thread_is_registered 来检查线程是否注册,如果没有我们注册并断言。我的应用程序可以通过多种方式调用 pj_dns_resolver_destroy。
1) 当应用程序在前台或后台时,网络发生变化。我们销毁当前的解析器并创建一个新的解析器。析构函数在检查 PJSIP 的线程注册后调用 pj_dns_resolver_destroy。
2) 在应用程序关闭时(可能在前台或后台),我们从服务的 OnDestroy 方法销毁 C++ 堆栈。
问题:
Android O wrt 线程本地存储或内存管理 wrt 后台服务等是否有任何可能触发此行为的更改?
解决方案
推荐阅读
- database-design - 如何在不创建额外表的情况下存储冗余数据?
- javascript - JavaScript/React Native 数组(对象)排序
- node.js - 2 Way SSL 证书的 CN 名称
- python - 为什么高级索引会创建切片矩阵的副本?
- java - 获取 JSON 字符串的抽象语法树
- ios - UITableView - 在 sectionHeader 中调整FontSizeToFitWidth
- java - 使用流 StreamSupplier
- c# - 如何使用 streamreader 提取发送给我的单行?
- python - Python/AWS/conda - ImportError:无法导入名称'multiarray'
- svn - 我在哪里可以找到假的 svn 存储库?