testplanb / dyso Goto Github PK
View Code? Open in Web Editor NEWandroid 动态加载so库实现
android 动态加载so库实现
我是直接把jniLibs的so删了 运行 然后手动放app外部私有目录里,点击一个按钮加载so
错误信息是ib/arm64-v8a, /system/lib64, /system/product/lib64]]] couldn't find "libxxxx.so"😂 我debug看了 传的文件是存在的
你好,这边实际在使用时还是出现了,在so相互依赖时,so找不到的情况,如A依赖B,加载A时会出现找不到B的情况,这种如何解决呢
我看demo中不涉及这种情况
前置条件:
1、系统版本Android7.0、已Root
2、Demo代码未修改逻辑,只添加了几行日志
3、运行前已导入so [libnativecpp.so、libnativecpptwo.so]到此目录: /data/user/0/com.example.nativecpp/files/dynamic_so/
4、
arm-linux-androideabi-readelf -d libnativecpptwo.so
Dynamic section at offset 0xdc8 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libnativecpp.so]
0x0000000000000001 (NEEDED) Shared library: [liblog.so]
0x0000000000000001 (NEEDED) Shared library: [libm.so]
0x0000000000000001 (NEEDED) Shared library: [libdl.so]
0x0000000000000001 (NEEDED) Shared library: [libc.so]
0x000000000000000e (SONAME) Library soname: [libnativecpptwo.so]
5、$ /data/user/0/com.example.nativecpp/files/dynamic_so # ls -al
-rwxrwxrwx 1 root root 1414352 2023-03-01 11:48 libnativecpp.so
-rwxrwxrwx 1 root root 60120 2023-03-01 11:48 libnativecpptwo.so
运行日志如下:
2023-03-01 14:38:46.899 5737-5737/com.example.nativecpp I/hello: path /data/user/0/com.example.nativecpp/files/dynamic_so/
2023-03-01 14:38:46.905 5737-5737/com.example.nativecpp I/hello: dependencies: [libnativecpp.so, liblog.so, libm.so, libdl.so, libc.so]
2023-03-01 14:38:46.909 5737-5737/com.example.nativecpp I/hello: dependencies: [liblog.so, libm.so, libdl.so, libc.so]
2023-03-01 14:38:46.909 5737-5737/com.example.nativecpp I/hello: dependencySo: log
2023-03-01 14:38:46.910 5737-5737/com.example.nativecpp I/hello: dependencySo: m
2023-03-01 14:38:46.911 5737-5737/com.example.nativecpp I/hello: dependencySo: dl
2023-03-01 14:38:46.913 5737-5737/com.example.nativecpp E/linker: library "/system/lib64/libdl.so" ("/system/lib64/libdl.so") needed or dlopened by "/system/lib64/libnativeloader.so" is not accessible for the namespace: [name="classloader-namespace", ld_library_paths="", default_library_paths="", permitted_paths="/data:/mnt/expand:/data/data/com.example.nativecpp"]
2023-03-01 14:38:46.914 5737-5737/com.example.nativecpp D/AndroidRuntime: Shutting down VM
2023-03-01 14:38:46.914 5737-5737/com.example.nativecpp E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.nativecpp, PID: 5737
java.lang.UnsatisfiedLinkError: dlopen failed: library "/system/lib64/libdl.so" needed or dlopened by "/system/lib64/libnativeloader.so" is not accessible for the namespace "classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1530)
at com.example.lib_sillyboy.DynamicSo.loadStaticSo(DynamicSo.java:45)
at com.example.lib_sillyboy.DynamicSo.loadStaticSo(DynamicSo.java:38)
at com.example.nativecpp.MainActivity.onCreate(MainActivity.java:33)
at android.app.Activity.performCreate(Activity.java:6666)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2677)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2789)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6251)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
添加日志代码:
public class DynamicSo {
public static void loadStaticSo(File soFIle, String path) {
try {
ElfParser parser = null;
List dependencies = null;
try {
parser = new ElfParser(soFIle);
dependencies = parser.parseNeededDependencies();
} catch (Throwable e) {
throw e;
} finally {
if (parser != null) {
parser.close();
}
}
Log.i("hello", "dependencies: " + dependencies);
//如果nativecpp3->nativecpptwo->nativecpp 则先加载 DynamicSo.loadStaticSo(nativecpptwo),此时nativecpp作为nativecpptwo的直接依赖被加载了
//不能直接加载nativecpp3,导致加载直接依赖nativetwo的时候nativecpp没加载导致错误。 这个可以优化,比如递归
for (final String dependency : dependencies) {
try {
File file = new File(path + dependency);
if (file.exists()) {
//递归查找
loadStaticSo(file, path);
} else {
// so文件不存在这个文件夹,代表是ndk中的so,如liblog.so,则直接加载
// 把本来lib前缀和.so后缀去掉即可
String dependencySo = dependency.substring(3, dependency.length() - 3);
//在application已经注入了路径DynamicSo.insertPathToNativeSystem(this,file) 所以采用系统的加载就行
Log.i("hello", "dependencySo: " + dependencySo);
System.loadLibrary(dependencySo);
}
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException ignored) {
}
packagingOptions下增加
exclude 'lib/arm64-v8a/xxx.so'
exclude 'lib/armeabi-v7a/xxx.so'
即可在打包后自动移除对应的so,无需增加task
2022-08-29 15:46:34.714 7719-7719/com.liwei.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.liwei.myapplication, PID: 7719
java.lang.UnsatisfiedLinkError: dlopen failed: cannot locate symbol "__cxa_finalize" referenced by "/system/lib64/libdl.so"...
at java.lang.Runtime.loadLibrary(Runtime.java:372)
at java.lang.System.loadLibrary(System.java:1076)
at com.liwei.myapplication.lib_sillyboy.DynamicSo.loadStaticSo(DynamicSo.java:31)
at com.liwei.myapplication.MainActivity.onCreate(MainActivity.java:32)
at android.app.Activity.performCreate(Activity.java:6289)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2405)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2535)
at android.app.ActivityThread.access$900(ActivityThread.java:155)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1380)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:152)
at android.app.ActivityThread.main(ActivityThread.java:5497)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
load报错
直接使用System.load(path)是正常的
pika大佬你好,如果有多个无依赖关系的so,那就多次调用 loadSoDynamically么?
请问可以加个微信吗,有偿
在用demo尝试的时候,发生了这个错误
java.lang.UnsatisfiedLinkError: dlopen failed: "/data/data/com.exemple.myapplication/files/dynamic_so/libtest.so" has unexpected e_version: 65725
at java.lang.Runtime.loadLibrary0(Runtime.java:1071)
at java.lang.Runtime.loadLibrary0(Runtime.java:1007)
at java.lang.System.loadLibrary(System.java:1668)
at com.exemple.myapplication.TestSo.(TestSo.kt:41)
at com.exemple.myapplication.MainActivity.onCreate$lambda-3(MainActivity.kt:62)
at com.exemple.myapplication.MainActivity.$r8$lambda$04hyejgvbGZzKFahH40V5n53yRg(Unknown Source:0)
at com.exemple.myapplication.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
打印classLoader的时候,确认自定义的solib已经插入nativeLibraryDirectories
dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/cn.lgh.myapplication-8GvN7C-0ytdB_y8C5cgMpw==/base.apk"],nativeLibraryDirectories=[/data/user/0/com.exemple.myapplication/files/dynamic_so, /data/app/com.exemple.myapplication-8GvN7C-0ytdB_y8C5cgMpw==/lib/arm64, /data/app/com.exemple.myapplication-8GvN7C-0ytdB_y8C5cgMpw==/base.apk!/lib/arm64-v8a, /system/lib64, /hw_product/lib64, /system/product/lib64]]]
同时要加载的so库也已经放到/data/user/0/com.exemple.myapplication/files/dynamic_so目录下
求解
"java.lang.UnsatisfiedLinkError: dlopen failed: ""/data/data/com.example.demo/files/dynamic_so/libVECoreFFmpeg.so"" has invalid shdr offset/size: 20189888/1344
at java.lang.Runtime.loadLibrary0(Runtime.java:1077)
at java.lang.Runtime.loadLibrary0(Runtime.java:998)
at java.lang.System.loadLibrary(System.java:1657)
at YHlnQn.tDgmK.XBLtLhuy(DynamicSo.java:195)
at YHlnQn.tDgmK.XBLtLhuy(DynamicSo.java:105)
at YHlnQn.tDgmK.XBLtLhuy(DynamicSo.java:105)
at com.pika.sillyboy.DynamicSoLauncher.loadSoDynamically(DynamicSoLauncher.kt:3)
从远程服务器上下载 so,手动加载后会出现以上问题
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.