Android加载第三方SO的配置

2,805 阅读1分钟

常见两种方案:

1.放在project 模式下的libs下的armeabi、armeabi-v7a、arm64-v8a、x86 ...

等效于Android 模式下jniLibs(如果新建工程没有该目录,build.gradle添加下面这句话,sync一下就会出现,而且该模式下一定要加上下面这段代码,因为libs目录不是默认的jni目录,需要指定一下)

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}

2.project 模式下, src ->main下新建jniLibs文件夹,拷入对应的文件夹 armeabi、armeabi-v7a、arm64-v8a、x86 ...

上述两种方案,build后都可以在apk文件解压模式的lib目录下看见

有时候会在build文件里看见下面一句, 使用方式1的时候一定要配置

    ndk {
        abiFilters 'armeabi', 'armeabi-v7a' // ......
    } 

这是对so准备支持哪几种CPU架构的过滤,填上的最后都编进apk的,没填上的就不会编进。不写这句,上述两种方案的so目录默认都会编进apk,软件就会显得臃肿。

番外:有些sdk可能需要指定路径

下面这句就可以拿到默认路径

context.getApplicationInfo().nativeLibraryDir+"/"+ libname

所以我们也有另外的方式来放置我们的so文件,比如/src/main/assets等,然后在工程代码中将其copy至固定的文件夹中,然后再加载。

private static void copyFromAssets(Context context, String name, String destPath) {
    File file = new File(destPath);
    if (file.exists()) {
        return;
    }
    try {
        file.createNewFile();
        InputStream in = context.getAssets().open(name);
        if (in == null) {
            return;
        }
        OutputStream out = new FileOutputStream(file);
        byte[] buffer = new byte[4096];
        int n;
        while ((n = in.read(buffer)) > 0) {
            out.write(buffer, 0, n);
        }
        in.close();
        out.flush();
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}