You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决应用中不同版本libgnustl_shared.so的依赖冲突问题

多SDK依赖不同版本libgnustl_shared.so的冲突问题及替代解决方案

问题描述

我在应用中集成了SDK A与SDK B,二者均依赖libgnustl_shared.so但版本不同,导致加载冲突:

  • 若加载SDK A所需的版本,SDK B运行时出现符号缺失错误:
2024-01-22 16:18:45.786 17159-17159 MainActivity   D  initAkuvoxSDK
2024-01-22 16:18:45.804 17159-17159 Akuvox         E  null: initAKTalkSDK(6): initAKTalkSDK
2024-01-22 16:18:45.833 17159-17159 MainActivity   D  initSDK faild:dlopen failed: cannot locate symbol "vpx_codec_destroy" referenced by "/data/app/~~oEVKSXHX5pZYt2cfbKQxUA==/com.lifesmart.nature.feature.imou.app-W4ytQs2rHgy2kvJJ4im0qw==/base.apk!/lib/armeabi-v7a/libmediaengine.so"...
  • 若加载SDK B所需的版本,SDK A运行时出现另一个符号缺失错误:
2024-01-22 17:23:16.047 19126-19126 System.err W  java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "_ZNSsD1Ev" referenced by "/data/app/~~bAS2agkoBsPcKUDA9pUdcg==/com.lifesmart.nature.feature.imou.app-Rf3ByH7-rhJyJFcP7_velw==/base.apk!/lib/armeabi-v7a/libLechangeSDK.so"...
2024-01-22 17:23:16.048 19126-19126 System.err W    at java.lang.Runtime.loadLibrary0(Runtime.java:1087)
2024-01-22 17:23:16.048 19126-19126 System.err W    at java.lang.Runtime.loadLibrary0(Runtime.java:1008)
2024-01-22 17:23:16.048 19126-19126 System.err W    at java.lang.System.loadLibrary(System.java:1664)
2024-01-22 17:23:16.048 19126-19126 System.err W    at com.lechange.opensdk.a.<clinit>(Loader.java:18)
2024-01-22 17:23:16.048 19126-19126 System.err W    at com.lechange.opensdk.a.a(Loader.java:35)
2024-01-22 17:23:16.048 19126-19126 System.err W    at com.lechange.opensdk.api.LCOpenSDK_Api_Impl$SingletonHolder.<clinit>(LCOpenSDK_Api_Impl.java:58)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lechange.opensdk.api.LCOpenSDK_Api_Impl$SingletonHolder.a(LCOpenSDK_Api_Impl.java:50)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lechange.opensdk.api.LCOpenSDK_Api_Impl.initOpenApi(LCOpenSDK_Api_Impl.java:94)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lechange.opensdk.api.LCOpenSDK_Api.initOpenApi(LCOpenSDK_Api.java:48)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.pkg.sdk.SDKWrapper.init(SDKWrapper.kt:27)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.app.LeCameraDialogFragment$initData$1.invoke(LeCameraDialogFragment.kt:116)
2024-01-22 17:23:16.049 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.app.LeCameraDialogFragment$initData$1.invoke(LeCameraDialogFragment.kt:114)
2024-01-22 17:23:16.050 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.app.LeCameraDialogFragment.initData$lambda$2(LeCameraDialogFragment.kt:114)
2024-01-22 17:23:16.050 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.app.LeCameraDialogFragment.$r8$lambda$nctCiCHEf4Q0fUDv8wF2ZEwZznY(Unknown Source:0)
2024-01-22 17:23:16.050 19126-19126 System.err W    at com.lifesmart.nature.feature.imou.app.LeCameraDialogFragment$$ExternalSyntheticLambda0.onChanged(Unknown Source:2)
2024-01-22 17:23:16.050 19126-19126 System.err W    at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
2024-01-22 17:23:16.050 19126-19126 System.err W    at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
2024-01-22 17:23:16.050 19126-19126 System.err W    at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
2024-01-22 17:23:16.051 19126-19126 System.err W    at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
2024-01-22 17:23:16.051 19126-19126 System.err W    at androidx.lifecycle.LiveData$1.run(LiveData.java:91)
2024-01-22 17:23:16.051 19126-19126 System.err W    at android.os.Handler.handleCallback(Handler.java:938)
2024-01-22 17:23:16.051 19126-19126 System.err W    at android.os.Handler.dispatchMessage(Handler.java:99)
2024-01-22 17:23:16.052 19126-19126 System.err W    at android.os.Looper.loop(Looper.java:223)
2024-01-22 17:23:16.052 19126-19126 System.err W    at android.app.ActivityThread.main(ActivityThread.java:7660)
2024-01-22 17:23:16.052 19126-19126 System.err W    at java.lang.reflect.Method.invoke(Native Method)
2024-01-22 17:23:16.052 19126-19126 System.err W    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
2024-01-22 17:23:16.052 19126-19126 System.err W    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

应用配置:

  • minSdk 21
  • targetSdk 29
  • compileSdk 33

通过nm -D命令验证,两个版本的so符号互补:

nm -D /Users/hanwen/temp/so_conflict/libgnustl_shared_SDK_A.so | grep _ZNSsD1Ev
        0008adac W _ZNSsD1Ev
nm -D /Users/hanwen/temp/so_conflict/libgnustl_shared_SDK_A.so | grep vpx_codec_destroy
# no output

nm -D /Users/hanwen/temp/so_conflict/libgnustl_shared_SDK_B.so | grep _ZNSsD1Ev
# no output
nm -D /Users/hanwen/temp/so_conflict/libgnustl_shared_SDK_B.so | grep vpx_codec_destroy
    0005e92c T vpx_codec_destroy

目前已采用多进程方案隔离两个SDK,但内存占用较高,寻求其他可行解决方案。

替代解决方案

1. 合并两个版本的libgnustl_shared.so

由于两个so的符号互补(无同名冲突符号),可以将两者合并为一个包含所有必要符号的so:

  • 使用objcopy工具分别提取两个so的代码段、数据段
  • 将提取的段合并到一个新的libgnustl_shared.so中,处理重定位信息
  • 替换应用中原有的两个版本so,确保两个SDK都能找到所需符号

2. 静态链接libgnustl到SDK

  • 联系SDK提供商,要求提供静态链接libgnustl_static.a的版本,避免动态依赖冲突
  • 若无法获取源码,可尝试使用patchelf修改SDK的so,将动态依赖改为静态嵌入(需逆向工程基础,难度较高)

3. Android命名空间隔离(API 24+)

从Android 7.0(API 24)开始支持动态库命名空间,可分别为两个SDK创建独立的命名空间:

  • 加载SDK前,用dlopen打开对应版本的libgnustl_shared.so,指定RTLD_LOCAL和RTLD_NOW
  • 调用android_create_namespace创建独立命名空间,关联该so
  • 加载SDK的so时,指定使用对应命名空间,确保符号查找隔离
  • 针对minSdk 21的兼容:API >=24时使用该方案,API <24时 fallback到多进程

4. 符号补全

针对缺失的符号编写补全代码,编译成独立so提前加载:

  • 提取缺失符号的实现(比如从SDK B的libgnustl中提取vpx_codec_destroy),或编写兼容实现
  • 将补全代码编译成so,在加载SDK前先加载该so,让动态链接器找到缺失符号
  • 此方案适合符号缺失较少的场景,当前情况中补全一个符号即可解决冲突

内容的提问来源于stack exchange,提问作者Albert Culajay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:52:32