apk启动白屏,抓到log发现如下报错,
04-20 07:54:04.253 4916 4916 D MyApplication: Link Error: java.lang.UnsatisfiedLinkError: dlopen failed: library "libdmabufheap.so" not found: needed by /data/app/~~lye8PBvSv1C7FmFRgMFHVQ==/com.example.myapplication-Oktd5W73Ah4OisAM8D99OA==/lib/arm64/libcamera360.so in namespace classloader-namespace
libdmabufheap.so 实际上是存在于system/lib64 目录下的(Android 12 平台)。
产生该问题的原因是lib库的命名空间问题。
解决办法是在system/etc/public.libraries.txt,添加对应的so库,可以先pull出来,修改完再push 进去。
如果要修改进系统,在编译出image的时候带该功能,则可以在system\core\rootdir\etc\public.libraries.android.txt里面添加对应的so库即可。
知识延申:
动态链接器在运行时从存储器中找到共享库,将它们加载到内存中并链接它们的符号。
每当接收到库加载请求时,动态链接器遍历库搜索路径(Library Search Path, LSPath)来搜索该库。
动态链接器用 已加载库列表(Alread Loaded Library list, ALList)跟踪加载的库,以便进一步使用(如符号查找)。如果要求加载的库已经在 ALList 中,现有的数据将被直接使用——从而加速动态链接。
在Android N之前,在一个进程中,所有本地代码在 LSPath 下具有对共享库的相同访问权限;同时,所有加载的库都注册在同一个 ALList 中。
从 Nougat 开始,Android 动态链接器将一个进程的空间加载到多个 命名空间 中。每个 命名空间 都有自己的 LSPath 和 ALList 。每个 命名空间 只能访问自己的 LSPath 和 ALList 。
通过这种设计,库被加载在互相隔离的 命名空间 中,其他 命名空间 中的库对它们是不可见的。
然而,操作系统中显然有一些库需要对一个进程的所有代码可见,例如 NDK 。Android Oreo 引入了 命名空间链接 从而在 命名空间 之间共享库。
命名空间链接 是在两个 命名空间 之间创建的单向链接,用于将库从一个 命名空间 共享给另一个。链接 命名空间 还可以链接到其他 命名空间 。
为了实现禁止应用程序访问私有库并分别管理 Framework 和 Vendor 库的目标,Android 系统以不同的方式部署 命名空间 机制。