Android MK 依赖动态库

在开发 Android 应用程序时,我们经常会使用到第三方库或者系统提供的动态库,这些库文件通常是以.so文件的形式存在。Android.mk 是 Android 应用程序编译系统使用的一个脚本文件,它可以帮助我们在编译过程中正确地引入和使用动态库。

什么是动态库

动态库是一种在程序运行时被加载到内存中的库文件,它包含了一些可供程序调用的函数和数据。与静态库相比,动态库具有以下优势:

  • 节省存储空间:多个程序可以共享同一个动态库,减少了重复存储的冗余。
  • 灵活更新:当动态库发生变化时,只需要替换动态库文件,而不需要重新编译和重新发布程序。
  • 运行时加载:动态库在程序运行时才被加载到内存中,因此可以动态地加载和卸载库文件。

Android.mk 文件结构

Android.mk 是一个 GNU Makefile 格式的脚本文件,用于描述编译和链接 Android 应用程序的各个模块。下面是一个简单的 Android.mk 文件示例:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := myapp

LOCAL_SRC_FILES := myapp.cpp

LOCAL_SHARED_LIBRARIES := mylib

include $(BUILD_SHARED_LIBRARY)

在上面的示例中,我们通过 LOCAL_MODULE 指定了生成的动态库的名称为 myappLOCAL_SRC_FILES 指定了源文件为 myapp.cppLOCAL_SHARED_LIBRARIES 则指定了依赖的动态库为 mylib。最后通过 include $(BUILD_SHARED_LIBRARY) 来完成动态库的构建。

动态库的引入和使用

在 Android.mk 中通过 LOCAL_SHARED_LIBRARIES 来指定动态库的依赖关系。假设我们的应用程序需要依赖一个名为 mylib 的动态库,我们可以在 Android.mk 中添加如下代码来引入它:

LOCAL_SHARED_LIBRARIES := mylib

同时,我们需要在应用程序的源代码中使用到动态库中的函数或者数据。我们可以通过 #include 来引入头文件,并在代码中直接调用动态库中的函数。

#include <mylib.h>

void myFunction() {
    // 调用动态库中的函数
    mylib_function();
}

动态库的构建

在 Android Studio 中使用 Android.mk 构建动态库的过程如下:

  1. 在项目的根目录下创建一个名为 jni 的文件夹,并在该文件夹下创建一个名为 Android.mk 的文件。
  2. Android.mk 文件中编写动态库的构建脚本,包括指定 LOCAL_MODULELOCAL_SRC_FILESLOCAL_SHARED_LIBRARIES 等参数。
  3. jni 文件夹下创建一个名为 myapp.cpp 的源文件,并在其中编写动态库的代码。
  4. 使用 ndk-build 命令来构建动态库。该命令会自动读取 Android.mk 文件并根据文件中的指令来构建动态库。
  5. 构建成功后,动态库文件会生成在 libs 目录下的相应架构目录中。

动态库的加载和卸载

在应用程序中,我们可以通过 System.loadLibrary() 方法来加载动态库,并通过 System.unloadLibrary() 方法来卸载动态库。以下是一个简单的示例:

public class MainActivity extends AppCompatActivity {
    static {
        System.loadLibrary("myapp");
    }

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

        // 调用动态库中的函数
        myFunction();
    }

    public native void myFunction();
}

在上面的示例中,首先通过 System.loadLibrary("myapp") 加载了名为 myapp 的动态库。然后在 onCreate() 方法中调用了 myFunction() 方法,该方法是在动态库中定义的。