Android中的动态链接库(so)是什么?

Android中的动态链接库(so)是什么?

动态链接库

一种不可执行的二进制程序文件,它允许程序共享执行特殊任务所必需的代码和其他资源。
windows:dll文件
linux:so文件
mac os: dylib

Android中的动态链接库

众多周知安卓是基于linux所以在安卓中的动态链接库也是so文件。通俗点讲就是使用ndk编译出来的产物。

armeabi armeabi-v7a arm64-v8a x86 x86-64的区别

arm开头的表示的是arm公司(英国)出品的cpu处理器指令集。arm公司并不生产芯片,它通过设计指令,出售产权给其他公司(高通,三星等)来获取收益。
armeabi armeabi-v7a arm64-v8a都是他的产品。
armeabi:早期的产品,基本过时了,32位的
armeabi-v7a: 升级版本,v7a就是版本32位的
arm64-v8a:64位

x86和x86-64(x64)是intel(英特尔)公司的产品。
x86: 32位
x86-64: 64位

二者区别:
1.arm的产品已经占据手机市场cpu芯片的95%左右市场份额,(这种架构指令,可能不是同一家公司生产,比如高通,三星,台积电生产) 2.arm是一种精简指令集,功效小,效率高,性能略次 3.intel 主要是pc上的cpu,手机端很少使用,性能强悍,耗电

Android中的使用

有时侯为了性能,或者安全性(不易反编译)我们会使用到c/c++开发,然后通过jni调用。那么应该如何放置so文件呢?

1.arm和intel的不能混着放
比如把x86里面的放到arm中的任何一个(如armeabi-v7a)中,否则回报

java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.litets.android.hacker-FVZNp5xlPfKaNnLu28r3Ug==/lib/arm/libnative-lib.so" has unexpected e_machine: 3

原因:因为他们的指令不一样,就好比要飞机(arm)在天上飞,火车(x86)在轨道上跑,这时候你把火车丢到天上让他飞一样。
有一段jni代码

Java_com_litets_android_hacker_Tools_jiami(JNIEnv *env, jobject instance, jstring src_,
                                           jstring code_) {
    const char *src = env->GetStringUTFChars(src_, 0);
    const char *code = env->GetStringUTFChars(code_, 0);

    std::string s(src);
    for (int i = 0; i < s.length(); ++i) {
        LOG("%c", s[i]);
    }

    LOG("%s", s.c_str());


    env->ReleaseStringUTFChars(src_, src);
    env->ReleaseStringUTFChars(code_, code);

    return env->NewStringUTF(s.c_str());
}

分别生产了armeabi-v7a和x86的so文件然后我们看下他们的汇编指令
armeabi-v7a

x86

看一明显看出指令格式不同

  1. 64位的不能放到42位的里面
    java.lang.UnsatisfiedLinkError: dlopen failed: "/data/app/com.litets.android.hacker-Kgsp8Co12QvwGFlPLhl6Ng==/lib/arm/libnative-lib.so" is 64-bit instead of 32-bit

3.不能使用到了而没有放so
如java中使用到了某个so但是没有放置

static {
        System.loadLibrary("native-lib");
    }
java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/com.litets.android.hacker-i7ytppEehgWJgXrSFtPHNQ==/base.apk"],nativeLibraryDirectories=[/data/app/com.litets.android.hacker-i7ytppEehgWJgXrSFtPHNQ==/lib/arm64, /system/lib64, /vendor/lib64, /product/lib64]]] couldn't find "libnative-lib.so"

4.同平台向下兼容

5.不能缺少
比如使用到了a.so和b.so,在armeabi中放置了2个a.so和b.so,而在armeabi-v7a中放置了b.so, 这样的话,如果cup架构刚好是armeabi-v7a那么a.so就不not found,虽然v7a可以使用armeabi但是android系统此时就不会去armeabi中查找

建议

现在的手机通常都是arm架构的,所以为了减少包体积只放armeabi-v7a的即可,其他的可以动态下发。

获取手机的cpu架构

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            for (String supportedAbi : Build.SUPPORTED_ABIS) {
                Log.i("JNI", supportedAbi);
            }
   }else{
           String abi = Build.CPU_ABI;
            String abi2 = Build.CPU_ABI2;
   }
2019-05-22 11:33:23.179 18617-18617/? I/JNI: arm64-v8a
2019-05-22 11:33:23.179 18617-18617/? I/JNI: armeabi-v7a
2019-05-22 11:33:23.179 18617-18617/? I/JNI: armeabi
声明:原创文章,版权所有,转载请注明出处,https://litets.com。