导入现有的c ++库(.a或.so文件)ndk android

时间:2016-11-04 04:52:21

标签: android android-ndk java-native-interface .a .so

我刚刚在android中进行了本机开发。我成功地将 AndroidStudio 2.2.2 准备好用于本机发布

我还构建了示例 hello-jni 项目

我想要实现的目标

我正在尝试使用以c ++设计的现有库(我将提供静态库 .a 扩展名或 .so 文件)

关于本土发展的几点混淆

1)我应该使用.cpp&现有c ++库的.h文件而不是 .a .so 文件?

2)我是否需要制作 CMakeLists.text :据我搜索 .a文件,并非使用 ndk-build ,所以我需要做到。

如果我使用 .cpp& .h文件,我应该 Android.mk &的 Application.mk

CMakeLists.text 是否将我新开发的Android项目编译为库或我现有的 .a 文件?

3)我在哪里将 .a 文件放在我的项目中。它在 jni文件夹下吗?

4)我的java类文件是否应该定义与关键字native 相同的方法,就像在c ++文件中实现的那样(例如:在c ++文件方法名称getData()中,java类应该包含公共本机getData( ))

3 个答案:

答案 0 :(得分:16)

好的,所以你有很多问题。其中一些问题是个人偏好类型,但我会将它们作为我个人的选择。

1

这是你的选择。我个人会使用已编译的.so文件。这样我就不必担心NDK和CMake和.mk文件了。如果您有该文件,您只需将该文件添加到libs文件夹(而非lib文件夹)并对您的build.gradle文件进行微小更改。就是这样。

更改为build.gradle:

sourceSets {
    main {
        manifest.srcFile 'AndroidManifest.xml'
        java.srcDirs = ['src']
        res.srcDirs = ['res']
        assets.srcDirs = ['assets']
        jniLibs.srcDirs = ['libs']
    }
}

2& 3

这些与此选项无关。

4

无论您使用文件还是编译库,都必须执行此类操作:

@SuppressWarnings("JniMissingFunction")
public class MyNativeMethods {
    static {
        System.loadLibrary("my_native_lib");
    }

    public native int native_method_1(int fd);
    public native int native_method_2(int fd);
    public native void native_method_3(int fd, int arr[]);
    public native int[] native_method_4(int fd);
}

然后,您可以通过Activity / Fragment调用这些方法。

希望这很清楚。

编辑(根据以下评论)

1).so.a文件是您的本机库。

2).cpp.c等文件只是您的本机源代码文件。如果您要在项目中使用这些文件,则必须使用构建系统(例如,CMake)来使用它们。 CMake将获取您的源代码文件并创建一个.so库,这也是本机库。这就是为什么我建议使用.so文件,因为为什么在你不需要时在项目中实现CMake的工作呢?

如果您想尝试CMake或将来学习它,请查看以下答案:C/C++ with Android Studio version 2.2

3)System.loadLibrary("my_native_lib");:这里告诉Java运行时添加这个给定的库。这样,您就可以在Java和库中的C ++代码之间创建链接。该行下面的方法应该与它们在C ++ / C代码中的名称相同。这样,Java运行时将找到并打开库,并在您加载的库中查找这些方法。查看更多here

答案 1 :(得分:1)

来自here

  

直接从APK打开共享库

     

在API级别23及以上版本中,可以直接从APK打开.so文件。只需正常使用System.loadLibrary(“foo”),但在AndroidManifest.xml中设置android:extractNativeLibs =“false”。在旧版本中,.so文件是在安装时从APK文件中提取的。这意味着他们占用了你的APK空间并再次放在你的安装目录中(这被计算在内,并向用户报告为你的应用占用的空间)。您要直接从APK加载的任何.so文件必须在zip文件中页面对齐(在4096字节的边界上)并且未压缩存储。当前版本的zipalign工具负责对齐。

     

请注意,在API级别23及以上版本中,dlopen(3)将从任何zip文件中打开一个库,而不仅仅是您的APK。只需给dlopen(3)一个“my_zip_file.zip!/libs/libstuff.so”形式的路径。与APK一样,库必须是页面对齐的,并且未压缩存储才能使其正常工作。

答案 2 :(得分:0)

这可能有助于您Add C and C++ Code to Your Project