1:加载 so 

System.load() 或 System.loadLibrary() 区别

在 Java 中,System.load() 和 System.loadLibrary() 都是用于加载本地库(Native Library)的方法。本地库是一种使用本地语言(如 C 或 C++)编写的库,可以通过 Java Native Interface(JNI)在 Java 中调用。

System.load() 方法用于加载指定的本地库文件,需要指定本地库文件的完整路径。例如:

System.load("/path/to/mylibrary.so");

System.loadLibrary() 方法用于加载指定的本地库,需要指定本地库的名称。在加载本地库之前,需要将本地库文件放置在系统路径中,或者使用 -Djava.library.path 参数指定本地库文件的路径。例如:

System.loadLibrary("mylibrary");

System.loadLibrary() 方法会自动将本地库名称转换为操作系统特定的库文件名称,并在系统路径中查找该库文件。例如,在 Linux 系统中,System.loadLibrary("mylibrary") 方法会自动查找名为 libmylibrary.so 的库文件。

因此,System.load() 和 System.loadLibrary() 的主要区别在于,System.load() 方法需要指定本地库文件的完整路径,而 System.loadLibrary() 方法只需要指定本地库的名称,并自动查找库文件。在使用时,可以根据实际情况选择使用哪种方法。

个人建议尽量使用 System.loadLibrary()  方法,相对于System.load() ,System.loadLibrary()  会更安全。

2: 多个so 之间相互依赖

在 Android 应用程序中,不同的动态链接库之间可能会存在相互依赖的情况。例如,一个库可能需要调用另一个库中的函数或数据,从而实现某些功能。

定依赖关系:在使用多个动态链接库时,需要先确定它们之间的依赖关系。例如,库 A 可能需要调用库 B 中的函数或数据,因此库 A 依赖于库 B。在确定依赖关系后,可以按照依赖关系的顺序加载库,从而确保每个库都能够正确地调用其依赖的库。

加载顺序:在加载动态链接库时,需要按照依赖关系的顺序加载库。

!!!注意:在不同的目录下载,相互依赖的so,会出现找不到的情况

例子:如果so 动态下载,多个so 之际存在依赖,但是so 下载在不同目录下,如果库 A 依赖于库 B,则需要先加载库 B,再加载库 A。这样可以确保每个库都能够正确地调用其依赖的库。否则,没有先加载B,先加载A,则会直接异常。

3: 异常兼容

加载so 是 主要使用 try - error , try - catch 不一定可以兜住加载so的逻辑,最常见错误:java.lang.UnsatisfiedLinkError

!!!注意:如果so 动态下载,确保只有一个线程进行下载,多线程下载会造成文件异常损坏。如果想要判断是文件是否有顺坏,可考虑通过文件对比md5的方式,进行校验。

4:jar包混淆 ProGuard 规则

-keep class com.xx.xxx.** { *; } 是一个 ProGuard 规则,用于指示 ProGuard 工具在混淆代码时保留 com.xx.xxx 包中的所有类和成员。这个规则通常用于防止 ProGuard 混淆某些第三方库或 SDK 中的代码,以确保这些库或 SDK 在应用程序中正常工作。

!!!注意:如果不配置混淆,可能导致debug 包下,第三方sdk功能使用正常,但是在生成release包,第三方功能丢失

5:pag资源加载so 和 初始化时机异步

问题:pag动效调用前,需要动态下载pag so并load, 动态下载load pag so资源是viewmodel异步下载下载阻塞的,偶现布局初始化的时机过早,so资源没有load,调用pagview导致crash

解决方案:

调整初始化sdk相关的初始化时在下载并加载so资源之后。!!切记pagview 不要放在init方法或xml布局里去实现调用。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐