首页 > 解决方案 > 用于后台服务的 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 后台服务等是否有任何可能触发此行为的更改?

标签: androidmultithreadingandroid-8.0-oreopjsipthread-local-storage

解决方案


推荐阅读