so_solr - CSDN
精华内容
参与话题
  • 一.添加aar 1.1什么是aar AAR是Google为Android Studio专门推出的一种库文件格式,Eclipse没办法像使用jar那样直接使用AAR文件,但是我们可以使用AAR里面的文件快速创建一个Eclipse Library项目,然后在我们的项目...

    一.添加aar

    1.1什么是aar

    AARGoogleAndroid Studio专门推出的一种库文件格式,Eclipse没办法像使用jar那样直接使用AAR文件,但是我们可以使用AAR里面的文件快速创建一个Eclipse Library项目,然后在我们的项目中引用即可。

    1.2aar和jar包的区别

    *.jar:只包含了class文件与清单文件,不包含资源文件,如图片、布局等所有res中的文件。
    *.aar:包含所有资源,class以及res资源等全部文件。

    如果你只需要一个简单的类库,那么使用生成的*.jar文件即可;如果你需要的是一个UI库,包含一些自己写的控件布局以及字体等资源文件,那么就只能使用*.aar文件。将代码打包成aar文件可以在一定程度上加快Android Studio的加载速度,尤其是将Module打包成aar文件提升的效果会更加显著。


    1.3aar在在Android Studio中的使用

    1. 将要集成的AAR文件拷贝到工程的libs目录下;

    2. 在项目工程的build.gradle配置文件中做以下配置:

    如下图添加:

    repositories {
        flatDir {
            dirs 'libs'
        }
    }

    dependencies {
     implementation(name: 'IMeasureSDK', ext: 'aar')
    }

    二.添加So包

    2.1什么是so包

    Android 系统本质是一个经过改造的 Linux 系统,so库是Linux系统上使用的共享库(类似windows上的dll)。最早,Android 系统只支持 ARMv5 的 CPU 构架,随着 Android 系统的发展,又加入了 ARMv7 (2010), x86 (2011), MIPS (2012), ARMv8, MIPS64 和 x86_64 (2014)。每一种 CPU 构架,都定义了一种 ABI(Application Binary Interface),ABI 决定了二进制文件如何与系统进行交互。

    详情请看我之前的文章:https://blog.csdn.net/xxdw1992/article/details/87157582

    2.2在build文件中配置

    defaultConfig {
            ndk {
                abiFilters "armeabi", "armeabi-v7a","arm64-v8a", "x86", "x86_64", "mips", "mips64"
            }
        }
    
    
    
    //    读取libs中的so文件
        sourceSets {
            main {
                jniLibs.srcDirs = ['libs']
            }
        }

    2.3为什么要设置ndk的abiFilters

    其实这个可以不设置,这样编译时,就会将项目里所有依赖资源包里的so库都打到最终的apk里。

    但是有些平台,我们是不需要支持的,如果不删除的话,apk就臃肿了。如果那些so库是我们自己编译出来的,那可以直接在工程中删除对应so文件,但是如果是第三方提供的,就不好删除了,所以就需要使用abiFilters来过滤了。

    如果需要针对不同的平台出不同的包,可以在productFlavors里进行设置,可参考文章:https://blog.csdn.net/hknock/article/details/76034125

    armeabi、armeabi-v7a、arm64-v8a的兼容性问题

    看上上面的描述,以为新增一个so库文件可以随便根据需要适配的目录放,就错了。如果你有库文件在armeabi里有,但是armeabi-v7a目录下没有,那么运行在V7a的架构时,就会出现找不到so库文件的情况。具体描述参照:Android 关于arm64-v8a、armeabi-v7a、armeabi、x86下的so文件兼容问题

    正确的做法

    1. 当前市面绝大多数是arm的CPU,而且都是V7架构的了,所以可以保留armeabi或者armeabi-v7a即可。
    2. 如果仅保留armeabi-v7a,而有些第三方包未提供v7a的包,则可以将对应armeabi包拷贝到armeabi-v7a。
    3. 如果同时保留armeabi和armeabi-v7a,则需要保证两个目录下的so库文件数相同。

    安卓开发技术分享: https://www.jianshu.com/p/442339952f26

    2.4常见问题

    2.4.1gradle文件中添加: sourceSets { main { jniLibs.srcDirs = ['libs'] } }会报错误

    如果有jniLibs目录就不需要设置Jni so文件路径

    三.添加依赖项目

    现在settings.gradle添加依赖项目的名字

    选中Module Dependency勾选确定就可以添加依赖

    四.添加依赖包

    输入你要添加的依赖包,搜索添加即可,右边是版本号

    五.新建jniLibs文件夹

    5.1添加jniLibs.srcDirs = ['libs']

    在moudle的build文件中添加

    在bulidTypes {} 结束后添加此段代码,

    sourceSets{  

          main{  

              jniLibs.srcDirs=['libs']  

          }  

      }  

    记住该段代码是包含在android{} 里头的

    5.2新建文件夹

    找到如下路径app--src--main,右击main 文件夹 ,选择New ,新建Directory

    然后文件夹命名jniLibs,往里头添加so 文件后就在目录中就能像res文件夹 显示了

    或者直接如下创建:

    六.Android 找不到so库(系统非公开库)文件

     

    导入第三方sdk,运行报错:
    java.lang.UnsatisfiedLinkError: dlopen failed: library “libskia.so” not found。
    一直以为是arr内部引用的私有so库文件出的问题,搜索了一下发现libskia.so是系统库文件(其他常用系统so库 libandroid_runtime.so、libcutils.solibcrypto.so ,libssl.so),从 Android 7.0 开始,系统阻止应用动态链接非公开 NDK 库
    解决方法:

    1. targetSdkVersion 设置为23及23以下
    2. 将so文件复制到项目armeabi-v7a文件夹下

    链接:

    https://blog.csdn.net/lihuapinghust/article/details/45825063

    https://www.cnblogs.com/janehlp/p/7473240.html

    https://zhuanlan.zhihu.com/p/21359984

    七.so包的拷贝策略

    1. 1)针对 armeabi 和 armeabi-v7a 两种 ABI

      方法1:由于 armeabi-v7a 指令集兼容 armeabi 指令集,所以如果损失一些应用的性能是可以接受的,同时不希望保留库的两份拷贝,可以移除 armeabi-v7a 目录和其下的库文件,只保留 armeabi 目录;比如 apk 使用第三方的 so 只有 armeabi 这一种 abi 时,可以考虑去掉 apk 中 lib 目录下 armeabi-v7a 目录。

      方法2:在 armeabi 和 armeabi-v7a 目录下各放入一份 so;

    2. 2)针对x86

      目前市面上的x86机型,为了兼容 arm 指令,基本都内置了 libhoudini 模块,即二进制转码支持,该模块负责把 ARM 指令转换为 X86 指令,所以如果是出于 apk 包大小的考虑,并且可以接受一些性能损失,可以选择删掉 x86 库目录, x86 下配置的 armeabi 目录的 so 库一样可以正常加载使用;

    3. 3)针对64位 ABI

      如果 app 开发者打算支持64位,那么64位的 so 要放全,否则可以选择不单独编译64位的 so,全部使用32位的 so,64位机型默认支持32位 so 的加载。比如 apk 使用第三方的 so 只有32位 abi 的 so,可以考虑去掉 apk 中 lib 目录下的64位 abi 子目录,保证 apk 安装后正常使用。

    参考网址:http://crash.163.com/#news/!newsId=5

     

    展开全文
  • linux下so动态库一些不为人知的秘密

    千次阅读 2018-07-04 17:55:35
    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名。二者都使用广泛。本文主要讲动态库方面知识。 基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看...

     linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名。二者都使用广泛。本文主要讲动态库方面知识。

       
       基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些动态库,使用ldd命令查看 
    1. # ldd /bin/ls
    2. linux-vdso.so.1 => (0x00007fff597ff000)
    3. libselinux.so.1 => /lib64/libselinux.so.1 (0x00000036c2e00000)
    4. librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
    5. libcap.so.2 => /lib64/libcap.so.2 (0x00000036c4a00000)
    6. libacl.so.1 => /lib64/libacl.so.1 (0x00000036d0600000)
    7. libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
    8. libdl.so.2 => /lib64/libdl.so.2 (0x00000036c1600000)
    9. /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
    10. libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
    11. libattr.so.1 => /lib64/libattr.so.1 (0x00000036cf600000)

       这么多so,是的。使用ldd显示的so,并不是所有so都是需要使用的,下面举个例子

    main.cpp
    1. #include <stdio.h>
    2. #include <iostream>
    3. #include <string>
    4. using namespace std;
    5. int main ()
    6. {
    7.    cout << "test" << endl;
    8.    return 0;
    9. }
       使用缺省参数编译结果
    1. # g++ -o demo main.cpp
    2. # ldd demo
    3.     linux-vdso.so.1 => (0x00007fffcd1ff000)
    4.         libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4d02f69000)
    5.         libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
    6.         libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
    7.         libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
    8.         /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
       如果我链接一些so,但是程序并不用到这些so,又是什么情况呢,下面我加入链接压缩库,数学库,线程库
    1. # g++ -o demo -lz -lm -lrt main.cpp
    2. # ldd demo
    3.         linux-vdso.so.1 => (0x00007fff0f7fc000)
    4.         libz.so.1 => /lib64/libz.so.1 (0x00000036c2600000)
    5.         librt.so.1 => /lib64/librt.so.1 (0x00000036c2200000)
    6.         libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff6ab70d000)
    7.         libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
    8.         libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
    9.         libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
    10.         libpthread.so.0 => /lib64/libpthread.so.0 (0x00000036c1a00000)
    11.         /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)

      看看,虽然没有用到,但是一样有链接进来,那看看程序启动时候有没有去加载它们呢

    1. # strace ./demo
    2.     execve("./demo", ["./demo"], [/* 30 vars */]) = 0
    3.     ... = 0
    4.     open("/lib64/libz.so.1", O_RDONLY) = 3
    5.     ...
    6.     close(3) = 0
    7.     open("/lib64/librt.so.1", O_RDONLY) = 3
    8.     ...
    9.     close(3) = 0
    10.     open("/usr/lib64/libstdc++.so.6", O_RDONLY) = 3
    11.     ...
    12.     close(3) = 0
    13.     open("/lib64/libm.so.6", O_RDONLY) = 3
    14.     ...
    15.     close(3) = 0
    16.     open("/lib64/libgcc_s.so.1", O_RDONLY) = 3
    17.     ...
    18.     close(3) = 0
    19.     open("/lib64/libc.so.6", O_RDONLY) = 3
    20.     ...
    21.     close(3) = 0
    22.     open("/lib64/libpthread.so.0", O_RDONLY) = 3
    23.     ...
    24.     close(3) = 0
    25.     ...
      看,有加载,所以必定会影响进程启动速度,所以我们最后不要把无用的so编译进来,这里会有什么影响呢?
       大家知不知道linux从程序(program或对象)变成进程(process或进程),要经过哪些步骤呢,这里如果详细的说,估计要另开一篇文章。简单的说分三步:
        1、fork进程,在内核创建进程相关内核项,加载进程可执行文件;
        2、查找依赖的so,一一加载映射虚拟地址
        3、初始化程序变量。
      可以看到,第二步中dll依赖越多,进程启动越慢,并且发布程序的时候,这些链接但没有使用的so,同样要一起跟着发布,否则进程启动时候,会失败,找不到对应的so。所以我们不能像上面那样,把一些毫无意义的so链接进来,浪费资源。但是开发人员写makefile 一般有没有那么细心,图省事方便,那么有什么好的办法呢。继续看下去,下面会给你解决方法。
      先使用 ldd -u demo 查看不需要链接的so,看下面,一面了然,无用的so全部暴露出来了吧
    1. # ldd -u demo
    2. Unused direct dependencies:
    3.         /lib64/libz.so.1
    4.         /lib64/librt.so.1
    5.         /lib64/libm.so.6
    6.         /lib64/libgcc_s.so.1
      使用 -Wl,--as-needed 编译选项
    1. # g++ -Wl,--as-needed -o demo -lz -lm -lrt main.cpp
    2. # ldd demo
    3.         linux-vdso.so.1 => (0x00007fffebfff000)
    4.         libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007ff665c05000)
    5.         libc.so.6 => /lib64/libc.so.6 (0x00000036c1200000)
    6.         libm.so.6 => /lib64/libm.so.6 (0x00000036c1e00000)
    7.         /lib64/ld-linux-x86-64.so.2 (0x00000036c0e00000)
    8.         libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00000036c7e00000)
    9. # ldd -u demo
    10. Unused direct dependencies:
    展开全文
  • C语言调用so动态库的两种方式

    万次阅读 多人点赞 2018-07-23 00:27:02
    这种方式生成的程序会在启动时候就加载so动态库。 add.h int add(int x, int y); add.c #include &quot;add.h&quot; int add(int x, int y) { return (x + y); } main.c #include &amp;lt;...

    方式1:类似静态库的调用(使用头文件)

    这种方式生成的程序会在启动时候就加载so动态库。

    add.h

    int add(int x, int y);

    add.c

    #include "add.h"
    
    int add(int x, int y) {
        return (x + y);
    }

    main.c

    #include <stdio.h>
    #include "add.h"
    
    int main()
    {
        int sum = add(7, 8);
        printf("7+8 = %d\n", sum);
    
        return 0;
    }

    编译so,生成libadd.so。

    gcc -shared -o libadd.so add.c

    编译main,使用-L./指定add库在当前目录。

    gcc -o main main.c -L./ -ladd

    方式2:使用dlopen/dlsum动态加载动态库(不使用头文件)

    这种方式生成的程序会在代码执行到指定行位置加载so动态库。

    add.c

    int add(int x, int y) {
        return (x + y);
    }

    main.c

    #include <stdio.h>
    #include <dlfcn.h>
    
    int main()
    {
        /*手动加载指定位置的so动态库*/
        void* handle = dlopen("./libadd.so", RTLD_LAZY);
        int (*add)(int a, int b);
    
        /*根据动态链接库操作句柄与符号,返回符号对应的地址*/
        add = dlsym(handle, "add");
    
        int sum = add(7, 8);
        printf("7+8 = %d\n", sum);
    
        dlclose(handle);
        return 0;
    }

    编译so,生成libadd.so

    gcc -shared -o libadd.so add.c

    编译main,不需要指定libadd.so相关信息进行编译,执行时候会在指定目录加载so

    gcc -o main main.c -ldl

    两种调用方式总结

    方式1使用头文件,所以可以直接调用头文件声明的函数。编译的时候指定了动态库位置和名称,程序启动时候系统就会自动加载相应位置的so动态库。
    方式2没有头文件,编译的时候也不需要指定动态库信息。但是需要在程序中使用dlopen函数加载相应位置的so动态库,且要使用dlsym函数根据函数符号去查找此函数的地址。


    BONUS: so动态库中调用so动态库

    add.h

    int add(int x, int y);

    add.c

    #include "add.h"
    
    int add(int x, int y) {
        return (x + y);
    }

    sum.h

    void printsum(int a, int b);

    sum.c

    #include "sum.h"
    #include <stdio.h>
    #include "add.h"
    
    void printsum(int a, int b){
        int sum = add(a, b);
        printf("%d+%d = %d\n", a, b, sum);
    }

    main.c

    #include "sum.h"
    
    int main()
    {
        printsum(1, 3);
        return 0;
    }

    编译libadd.so

    gcc -shared -o libadd.so add.c

    编译libsum.so,需要指定libadd.so信息

    gcc -shared -o libsum.so sum.c -L. -ladd

    编译main,仅需要指定libsum.so

    gcc -o main main.c -L. -lsum

    main运行的时候同时需要libsum.so 和 linadd.so。

    展开全文
  • 什么是.so文件

    千次阅读 2012-10-21 12:41:22
    .so文件是Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据 linux下何谓.so文件:1. 用过windows的同学应该都知道 .dll文件吧, 这二者有什么共通之处呢,其实 .so文件就跟.dll文件差不多.// ...

    .so文件是Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据


    linux下何谓.so文件:1. 用过windows的同学应该都知道 .dll文件吧, 这二者有什么共通之处呢,其实 .so文件就跟.dll文件差不多.//

    2.一般来说.so文件就是常说的动态链接库, 都是C或C++编译出来的。与Java比较就是:它通常是用的Class文件(字节码).//
    3.Linux下的.so文件时不能直接运行的,一般来讲,.so文件称为共享库.//
    4.那么.so文件是怎么用的呢?
    for example:(1)动态库的编译
    这里有一个头文件:so_test.h,三个.c文件:test_a.c、test_b.c、test_c.c,我们将这几个文件编译成一个动态库:libtest.so。
    命令:$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so 
    参考2:都是由C或C++编译出来的
    -shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
    -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
    (2)动态库的链接
    这里有个程序源文件 test.c 与动态库 libtest.so 链接生成执行文件 test:
    命令:$ gcc test.c -L. -ltest -o test
    注:测试是否动态连接,如果列出libtest.so,那么应该是连接正常了
    -L.:表示要连接的库在当前目录中
    -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
    命令:$ ldd test
    (注:执行test,可以看到它是如何调用动态库中的函数的。
    展开全文
  • 关于so文件你需要知道的知识

    千次阅读 2018-06-29 13:53:41
    1. 什么是CPU架构及ABIAndroid系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年...应用程序二进制接口(Application Binary Interface)定义了二进制文件(尤其是.so文件)如何运行在...
  • 理解Linux的.a、.so和.o文件

    千次阅读 2019-07-29 21:47:55
    在说明Linux的.a、.so和.o文件关系之前,先来看看windows下obj,lib,dll,exe的关系 windows下obj,lib,dll,exe的关系 lib是和dll对应的。lib是静态链接库的库文件,dll是动态链接库的库文件。 所...
  • Java调用so文件

    万次阅读 热门讨论 2019-02-14 11:39:06
    公司的硬件让我帮忙调用一个so文件,想着一直都没机会自己写一个jni,于是就答应了,在调用的过程中还踩了不少坑,特地写一篇博客记录一下。 一、使用技术 原本是想直接用java自带的jni,但是我们硬件只给了一个so...
  • 设置套接字超时的第三个技术是使用套接字选项 SO_RCVTIMEO 与 SO_SNDTIMEO,它的优势在于一次设置,所有应用于该套接字的操作都自动带有超时时间。它就好像是一个全局开关。比如对于 SO_RCVTIMEO 来说,如果设置了它...
  • 中英文电子书下载:https://sobooks.cc/

    万次阅读 2017-09-29 23:45:24
    电子书下载:sokindle.com★ 1....此网站界面清新,看着很舒服。 注:右边有搜索框,在手机上打开此网址,需要以“桌面模式”或“PC模式”打开,才能看到搜索框。★ 2.... 2017年9月29日出版的,AZW3格式。...
  • 访问测试项目路径localhost:8080/hello 后台抛出异常:This application has no explicit mapping for /error, so you are seeing this as a fallback. 抛出此异常表示访问的页面url没有匹配到对应的值,原因有如下...
  • 为什么你需要重点关注so文件 App中可能出错的地方 其他地方也可能出错 使用android-21平台版本编译的so文件运行在android-15的设备上 混合使用不同C运行时编译的so文件 没有为每个支持的CPU架构提供对应的so文件 将...
  • Android so加固的简单脱壳

    千次阅读 2017-09-24 16:24:21
    Android应用的so库文件的加固一直存在,也比较常见,特地花时间整理了一下Android so库文件加固方面的知识。本篇文章主要是对看雪论坛《简单的so脱壳器》这篇文章的思路和代码的分析,很久之前就阅读过这篇文章但是...
  • 360加固保so动态脱壳

    千次阅读 2016-12-12 10:27:48
    环境及工具 手机 : 中兴 U887 系统版本: Android 2.3.5 工具 : IDA pro 6.6 、0101Editor ...目前so加壳有很多家,我己知的有 爱加密,梆梆,360, 娜迦等 各有所长。...1.对加壳后的so进行反编译,
  • Android 调用so库全过程

    万次阅读 多人点赞 2017-12-05 10:41:59
    Android中有时候为了效率以及平台开发库的支持,难免会用到NDK开发,那么都会产生一个so文件,通过native方法进行调用,开发和调用步骤很简单,这里就不多说了,本文主要来介绍,我们在使用so的时候总是会出现一些...
  • libxxx.so- text relocations问题的终极解决方案

    万次阅读 多人点赞 2017-04-02 20:34:42
    问题表现形式错误或警告日志当targetSdkVersion>=23且使用debug签名时,在6.0+的... E/linker: /data/app/packagename/lib/arm/libxxx.so: has text relocations W/System.err: java.lang.UnsatisfiedLinkError:
  • 解决Could not load dynamic library 'libcudart.so.10.0'的问题

    万次阅读 多人点赞 2019-10-15 19:26:09
    问题表现与分析 在安装了CUDA和CUDNN还有Tensorflow最新的2.0正式版本后,我在使用Pycharm写TF代码并运行时,遇到这样的问题 主要表现就是提示找不到动态库文件,扫了一眼文件名,都是CUDA的库文件,那怎么会说...
  • Android SO 加壳(加密)与脱壳思路

    万次阅读 2016-08-14 17:56:23
    0x01 常见的Android SO加壳(加密)思路 1.1 破坏Elf Header 将Elf32_Ehdr 中的e_shoff, e_shnum, e_shstrndx, e_shentsize字段处理,变为无效值。由于在链接过程中,这些字段是无用的,所以可以随意修改,这会...
  • 安卓so库你应该注意的事

    千次阅读 2015-12-27 12:10:16
    早期的Android系统几乎只支持ARMv5的CPU架构,你知道现在它支持多少种吗?7种! Android系统目前支持以下七种不同的CPU架构:ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86...
  • 讨论了SO_REUSEPORT和SO_REUSEADDR在BSD中的起源及其作用的区别。分析了不同操作系统中二者意义上的差别。
  • Android IDA So的动态调试大法

    万次阅读 多人点赞 2016-10-05 19:48:38
    下面就说关于在IDA中Android so的动态调试的问题以及在so的三个层次下断点的操作。 问题篇: 1.动态调试的作用以及与我们常说的脱壳区别之处? 2.IDA的下断点调试的原理? 3.有无反调试的步骤区别?以及原理? ...
1 2 3 4 5 ... 20
收藏数 1,582,169
精华内容 632,867
关键字:

so