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

安装时模块正常但按需动态模块Native库加载异常咨询

Native C++ Android应用本地化动态模块问题

背景

我正在对一个基于Native C的Android应用做本地化,核心代码均为C编写,所有文本通过编译宏控制(例如LANG_JP对应日语)。

我创建了名为module_jp的按需动态模块,在其build.gradle中添加了额外的C++编译参数:

// module_jp's build.gradle
plugins {
   id 'com.android.dynamic-feature'
}
android {
   ...

   defaultConfig {
      ...
      externalNativeBuild {
         cmake {
            cppFlags "-fno-rtti -DLUTF8 -DLANG_JP" // 此处添加LANG_JP编译宏
         }
      }
   }

同时编写了独立的CMakeLists.txt用于生成libnative-activity-jp.so库:

// module_jp's CMakeLists.txt
...
add_library( # 设置库名称
        native-activity-jp

        指定为共享库
        SHARED
        ...
...
target_include_directories(
        native-activity-jp PRIVATE
        ${PLAYCORE_LOCATION}/include
        )
...
target_link_libraries( # 关联依赖库
        native-activity-jp
...

应用启动时提供语言选择功能,在LanguageSelectionActivity中根据用户选择加载对应Native库:

// LanguageSelectionActivity
// 启动Native Activity进入主流程
private void StartMainActivity(String LanguageCode) {

   if (LanguageCode.equals("en")) System.loadLibrary("native-activity");
   else System.loadLibrary("native-activity-" + LanguageCode);

   // 初始化Intent启动主Native Activity
   Intent intent = new Intent(getApplicationContext(), NativeActivity.class);
   startActivity(intent);
   finish();
}

问题现象

本地测试完全正常,选择日语可正确显示翻译文本;但上传至Google封闭测试(Alpha)和内部应用共享后,日志显示module_jp已安装且libnative-activity-jp.so已加载,却仍显示英文内容,推测base模块的libnative-activity.so被优先加载。

已完成的排查

  • 通过adb备份并提取文件,确认libnative-activity-jp.so已正确安装在设备的data/data/<包名>/splitcompat/##/native-libraries目录
  • 使用提取出的库进行本地测试,可正常显示日语翻译
  • 将模块交付类型改为「安装时」后,在Google测试渠道中可正常工作

咨询问题

  1. 即使未调用System.loadLibrary("native-activity"),base模块的Native库是否仍会被优先加载?
  2. 为何模块设为「安装时」正常,设为「按需」就异常?

解答

问题1:base模块Native库是否会自动加载

是的。Android系统在启动NativeActivity时,会根据Manifest中关联的默认Native库(即base模块的libnative-activity.so)自动触发加载流程,无需手动调用System.loadLibrary。

这种自动加载的优先级高于手动加载的动态模块库,系统会先加载base库的符号,后续加载的libnative-activity-jp.so中同名符号无法覆盖已加载的base库符号,最终显示英文文本。

问题2:安装时正常、按需异常的原因

  • 当模块设为「安装时」交付时,动态模块的Native库会被放置到与base模块库相同的标准Native库目录(/data/app/<包名>/lib/<abi>/)。手动加载libnative-activity-jp.so后,系统后续尝试加载base库时会发现同名符号已存在,不会重复加载base库符号,因此能正常显示日语。
  • 当模块设为「按需」交付时,动态模块的Native库会被存放在SplitCompat的隔离目录(splitcompat/##/native-libraries)。系统加载base库时从标准路径读取,此时动态模块库的符号处于隔离空间,无法覆盖已加载的base库符号,最终仍使用base库的英文文本。

内容的提问来源于stack exchange,提问作者pleasebugmenot.mrg

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:55:18