Android Studio最新CMake使用教程(二): 生成共享库.so文件并在其他项目中引用

        在实际的Android开发中,我们经常要用到外部的动态链接库.so文件,有时我们是使用别人编译好的.so 文件,有时需要我们自己用NDK编译出.so文件,并且在另外的工程里使用。所以本文旨在编写自己的Jni并且编译生成特定的共享库.so文件,然后在另外的工程里使用该共享链接库。

        首先我们先创建一个Naive C++工程,具体创建方法见我上一篇博客。创建完成的目录结构大致如下:

 这里为了在调用.so文件时方便区分开来,我的工程名、包名以及共享库名和库源文件名都做了修改。所以对应的CMakeLists也做了修改:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.

cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library.
        testso-lib

        # Sets the library as a shared library.
        SHARED

        # Provides a relative path to your source file(s).
        testso-lib.cpp)

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.
        log-lib

        # Specifies the name of the NDK library that
        # you want CMake to locate.
        log)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.
        testso-lib

        # Links the target library to the log library
        # included in the NDK.
        ${log-lib})

在上篇博客里,我们知道初始创建的Native C++工程是在MainActivity调用Jni方法的,这里我们新建了一个接口类TestSoHelper,并通过这个类调用Jni方法。TestSoHelper的代码如下:

package com.test.mytestsoproject;

public class TestSoHelper {
    // Used to load the 'native-lib' library on application startup.
    static {
        System.loadLibrary("testso-lib");
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    public static native int intFromJNI(int a, int b);
}

对应的Jni方法是:

extern "C"
JNIEXPORT jint JNICALL
Java_com_test_mytestsoproject_TestSoHelper_intFromJNI(JNIEnv *env, jclass instance, jint a,
                                                         jint b) {

    // TODO
    int returnValue = a + b;

    return returnValue;
}

这个Jni的方法十分简单,方法传入两个整数,然后返回这两个数的和。关于Jni的编写,学过C语言的同学应该一看就会了,基本是跟C/C++编写一模一样,在此不再赘述。

下面就是对应的native方法的调用了,我这里在MainActivity里简单调用了一下,由于我们是为了编译成.so文件,给其他工程用的,所以在此不写native方法的调用也是可以的。下面是我的调用:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Example of a call to a native method
        TextView tv = findViewById(R.id.sample_text);
        tv.setText(TestSoHelper.intFromJNI(1,2) + "");
    }

}

基本是默认的工程,只是把要显示的文本改成了我Jni方法返回的数据。打包运行的结果就是在手机上输出数字1+2的和3。

然后我们把编写好的Jni封装成共享库.so。只需要点击Build \rightarrowMake Project即可生成.so文件。生成的.so文件可以在下面的路径下找到:app\build\intermediates\cmake\debug\obj。可以看到工程生成了对应不同android CPU架构的.so文件:

这样我们就可以在别的工程里使用该.so 文件了。

       这里我是直接用上篇博客创建的工程(MyTestProject)来引用这个共享库.so文件的,当然,理论上这个共享库可以被任意android工程引用。首先,我们要把刚才生成的共享库.so文件拷贝到我们要使用它的工程的libs文件夹下,最好是把不同CPU架构的.so文件都拷贝进去,这样我们的应用就能支持各种android系统:

然后,在build.gradle里添加以下代码:

 代码如下:

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

这是告诉工程要引用的共享库所在的位置。接下来把刚才生成.so文件的工程里的Jni接口类TestSoHelper拷贝到我们当前的工程里,注意,路径也必须与原工程相同!另外,该类里的native方法可能会显示为红色,无法解析,这个不用去管,程序可以正常编译运行。

 到这里我们就可以直接在当前工程(MyTestProject)里调用共享库里的方法了,简单的调用如下:

打包执行下,结果果然与之前一样!

        以上方法是我个人使用Android Jni 的经验,应该是比网上其他引用自编写共享库的方法简单很多,希望能帮助大家。如有错误和不足,希望大家指正!

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 使用 Gradle 构建工具进行编译和打包,生成 .so 动态链接,可以按照以下步骤进行: 1. 在 Android Studio 创建一个 C/C++ 模块,选择 File -> New -> New Module -> C/C++ Library,然后按照向导设置模块名称、语言类型和支持的 ABI。 2. 在模块的 build.gradle 文件,添加以下配置: ```groovy android { // 指定支持的 ABI,包括 armeabi-v7a、arm64-v8a、x86、x86_64 等 ndk { abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' } // 配置 CMakeLists.txt 文件路径 externalNativeBuild { cmake { path "CMakeLists.txt" } } } // 配置 CMake 版本 cmake { version "3.10.2" } ``` 3. 在模块的 src/main 目录下创建 jni 文件夹,并将 C/C++ 代码放入该文件。 4. 在 jni 文件夹下创建 CMakeLists.txt 文件,并编写编译选项和链接选项,指定生成 .so 文件的名称和路径,以及引入其他依赖等。例如: ```cmake # 设置编译选项 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") # 设置源文件路径 file(GLOB_RECURSE SOURCE_FILES "*.cpp") # 设置头文件路径 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) # 配置动态输出路径和名称 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}) set(CMAKE_LIBRARY_OUTPUT_NAME "native-lib") # 引入其他依赖 find_library(log-lib log) # 生成动态 add_library(native-lib SHARED ${SOURCE_FILES}) target_link_libraries(native-lib ${log-lib}) ``` 5. 点击 Android Studio 工具栏的 Build -> Make Project,进行编译和打包,生成 .so 动态链接。 6. 在模块的 build.gradle 文件查看生成的 .so 文件路径,例如: ```groovy android { externalNativeBuild { cmake { path "CMakeLists.txt" } } sourceSets { main { jniLibs.srcDirs = ['src/main/jniLibs'] } } } ``` 以上就是在 Android Studio 使用 Gradle 构建工具进行编译和打包,生成 .so 动态链接的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值