首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从另一个应用程序加载私有本机库?

如何从另一个应用程序加载私有本机库?
EN

Stack Overflow用户
提问于 2022-03-20 22:53:00
回答 2查看 268关注 0票数 0

我有两个应用程序A和B。apps使用DexClassLoader从应用程序B加载一个自定义视图类。

但是,如果应用程序B中的自定义视图加载私有本地库,则通过java.lang.System.loadLibrarydalvik.system.PathClassLoader与apk捆绑在一起。然后我得到

代码语言:javascript
运行
复制
 java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.example.app-b-xxx==/base.apk"],nativeLibraryDirectories=[/system/lib, /vendor/lib]]] couldn't find "my_native_lib.so"

如果我自己启动应用程序B,它就能够加载私有的本地库了。

这有支持吗?我知道DexClassLoader只加载类,但是这些加载的类能够调用它们自己绑定的本地库吗?

EN

回答 2

Stack Overflow用户

发布于 2022-03-21 00:07:25

你真的不应该像这样直接加载类,你可能会因此而惹上谷歌的麻烦。我相信这是对戏剧商店的TOS的反对。这也是不安全的--如果安装了其他同名的应用程序,假装是你,你就允许他们的代码以你的用户身份运行,这是一个巨大的安全问题。

但让我们忽略这一点。这就是它不能工作的原因--你的应用程序没有那个库。当您通过loadLibrary加载时,它正在查找一个特定的路径,该路径是应用程序本地的.so文件。在这个上下文中,“您的应用程序”是正在运行的应用程序,而不是代码来自的应用程序。所以它找错地方了。如果在这两个应用程序中都包含了.so文件,它可能会起作用。但是您显然需要知道实现细节才能使其工作,您不能使用它来加载任意类的库。

票数 0
EN

Stack Overflow用户

发布于 2022-05-27 11:15:16

如果您愿意使用一些反射,DexClassLoader包含一个名为pathList的私有字段,该字段包含一个名为addNativePath(Collection)的方法。

要获得App的本机库目录,您可以通过包管理器加载它。

代码语言:javascript
运行
复制
// assumes currently in an activity

val nativeLibraryPath = packageManager.getPackageInfo("com.package.name", 0).applicationInfo.nativeLibraryDir

val clClass = classLoader.javaClass
val plField = clClass.superclass.getDeclaredField("pathList")
plField.isAccessible = true

val plInst = plField.get(classLoader)
val plClass = plClass.javaClass

val anpMethod = plClass.getDeclaredMethod("addNativePath", Collection::class.java)
anpMethod.invoke(
  plInst,
  listOf(nativeLibraryPath)
)

请记住,由于使用了隐藏的API方法,这可能会在某些较新版本的Android中停止工作。(我编写的代码主要是在Android 11上测试的)

如果您使用System.loadLibrary加载本机库(基于所提供的错误似乎不是这种情况),那么只使用带有从App到本机库的绝对路径的System.load就可以工作,而无需使用类加载器。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71551268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档