-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
插件加载问题:无法找到 "liblog3a-lib.so" #1366
Comments
你发现extractSo没调用是正确的原因。 没调用的原因是none-dynamic形式的插件框架没有对齐dynamic的功能开发完整。none-dynamic存在是为了解耦,将插件框架本身动态化的代码和插件框架的代码分离开。实际上我们业务应用是不存在none-dynamic形式的。由于插件在动态更新,调用的系统接口随时会新增,所以插件框架不动态起来是不行的。我们没能力开发一个完全对齐系统接口的完善的插件框架。所以插件框架是需要和插件一起开发,一起动态发布的。 但技术层面上,none-dynamic单独跑起来,对齐dynamic的功能是完全可行的。在设计上也是更合理更优雅的。欢迎贡献这些代码。 具体到so加载这个问题。插件之所以能加载so,完全是因为Android系统本身允许随时load一个给定路径的so文件。插件框架只是基于这一点,模仿系统安装apk时解压so的逻辑,再向classloader设置默认的so搜索路径。 现在那个manager的逻辑,没有none-dynamic的设计,默认安装插件的形式一定是有动态的loader等apk。理论上应该将它拆分成none-dynamic manager和dynamic manager。但还需要拆分它管理的数据库。想一想就很麻烦。所以为了一个用不上的需求写这个重构是很不划算的。所以none-dynamic的sample就是那个样子了。 |
非常感谢作者详细且深入的解答。对于none-dynamic和dynamic的区别以及Shadow框架的设计理念,我现在有了更深的理解。 如果可能的话,我会尝试贡献代码来完善none-dynamic的功能。 再次感谢你的耐心解答和指导。 |
作者你好,我在none-dynamic中增加了extractSo的能力后,又遇到了一个新问题。 当尝试在插件apk中使用jna加载库"djcrypto"时: DJCryptoAPI djCryptoAPI = (DJCryptoAPI)Native.load("djcrypto", DJCryptoAPI.class); 其中插件apk使用的jna库,是通过白名单使用宿主的jna依赖。djcrypto库则位于插件apk中。 遇到了一个错误,导致应用闪退。错误信息如下: Caused by:java.lang.UnsatisfiedLinkError: Unable to load library 'djcrypto':
dlopen failed: library "libdjcrypto.so" not found
dlopen failed: library "libdjcrypto.so" not found
dlopen failed: library "libdjcrypto.so" not found
Native library (android-aarch64/libdjcrypto.so) not found in resource path (.)
com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:301)
com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:461)
com.sun.jna.Library$Handler.<init>(Library.java:192)
com.sun.jna.Native.load(Native.java:596)
com.sun.jna.Native.load(Native.java:570)
com.donjin.djcryptoapi.djcryptojna.DJCryptoAPI.<clinit>(DJCryptoAPI.java:22) 我怀疑这可能是因为Shadow框架没有兼容 期待你的回复,谢谢。 |
这个JNA只是一个第三方库而已,不需要针对它做什么兼容。 你可以debug一下插件classloader的创建参数。你的log上看它只在.目录中搜索so了。 另外你怀疑JNA是否需要特殊兼容之前,应该先测试dynamic方式下使用JNA是否正常。还有你修改完的none dynamic方式能否正常加载一个简单普通的apk打包的so。 |
作者你好: 问题:none dynamic方式能否正常加载一个简单普通的apk打包的so。 这点确实还有问题,宿主app里,调用System.loadlibrary插件里的so,加载失败,看起来没有在apk_lib里搜索这个so dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.tencent.weworklocal-WU1AFR8MZwFbnCGvt1IAWQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.tencent.weworklocal-WU1AFR8MZwFbnCGvt1IAWQ==/lib/arm64, /data/app/com.tencent.weworklocal-WU1AFR8MZwFbnCGvt1IAWQ==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]] couldn't find "libdjcrypto.so" 我额外增加了类似extractso的逻辑: try {
String filter = "lib/" + getAbi() + "/";
File soDir = new File(installedApk.libraryPath);
CopySoBloc.copySo(
new File(installedApk.apkFilePath),
soDir,
AppCacheFolderManager.getLibCopiedFile(soDir, partKey), filter);
} catch (InstallPluginException e) {
ALog.d(TAG, "extractSo fail", e);
}
// todo:yeconglu 支持odex
ShadowPluginLoader pluginLoader = mPluginLoader;
Future<?> future = null;
try {
future = pluginLoader.loadPlugin(plugin);
future.get(10, TimeUnit.SECONDS);
} catch (Exception e) {
ALog.d(TAG, "loadPlugin fail", e);
} 入参是有的installedApk.libraryPath是有值的: 请问是还需要做什么,才能加载到插件里的so呢? |
你还是没明白。so的搜索是在classloader上定义的搜索路径。你构造个插件的classloader,填写了解压so的路径,是为了让插件里的类能搜索到这些so。宿主的classloader你又没改过,你为啥会想在宿主里加载插件的so呢?你有这种需求,直接load一个绝对路径不就行了? |
作者你好, 你说的宿主加载so时,如果需要加载插件的so,可以load一个绝对路径,这点明白了。 但是目前我发现,插件apk加载插件里的so还是没有加载成功,表现为调用jni方法时,会报 2025-02-10 18:10:38.835 14063-14063 JSWebHandler com.tencent.weworklocal W |handleJsMessage|java.lang.UnsatisfiedLinkError: No implementation found for long com.sangfor.sdk.entry.SFServerSelector.createNative(java.lang.String, java.lang.Object) (tried Java_com_sangfor_sdk_entry_SFServerSelector_createNative and Java_com_sangfor_sdk_entry_SFServerSelector_createNative__Ljava_lang_String_2Ljava_lang_Object_2) 我有几个问题想请教的:
shadow是如何替换插件中
|
load找不到so就应该抛出异常了吧? 和so搜索路径相关的代码还有applicationinfo中的参数 这里shadow没什么自己发明的手段。你完全可以参考一般的Android知识。实在搞不懂建议问问AI。 |
作者你好,
我在使用Shadow框架时遇到了一个问题。当我尝试以非动态方式加载插件apk时,我发现在
/data/user/0/com.tencent.weworklocal/files/plugin.apk_lib
路径下没有找到任何文件,直接报错是找不到"liblog3a-lib.so"库。错误信息如下:
我留意到在
com.tencent.shadow.core.manager.BasePluginManager
类中有一个extractSo
方法,但我发现这个方法只在动态加载插件的情况下被调用。我想请问,如果我想以非动态方式加载插件,是否还需要调用其他函数来解压so文件?如果是的话,能否提供一些指导或者示例代码?
期待你的回复,谢谢。
The text was updated successfully, but these errors were encountered: