当前位置: 首页>移动开发>正文

flutter golang 搜索引擎 flutter so库

调用图

flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_flutter,第1张

说明:flutter通过MethonChannel方式调用android原生接口,借助android的jni开发能力调用fmod库

准备工作
  1. 下载FMOD库
    FMOD官网
  2. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_flutter golang 搜索引擎_02,第2张


  3. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_c++_03,第3张

  4. 选择Android支持库下载,解压下载好的压缩文件, api/core/inc目录和api/core/lib目录下的文件就是之后项目中需要用到的c++的头文件和.so库,api/core/lib目录下包含了适用于不同ABI的.so文件
  5. Android Studio安装插件
  6. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_jni_04,第4张

flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_android_05,第5张

这里有一个需要注意的点,勾选Show Package Details查看NDK下具体安装了那些版本的NDK,上图中是我所下载并安装的NDK的版本,我曾经尝试将所有版本的NDK都勾选,然后下载并安装所有版本的NDK,再运行程序,会报错,错误的内容是FMOD头文件中定义的一些属性跟全局定义的属性冲突了,我猜测是因为FMOD头文件中的一些属性,跟某个版本的NDK中的属性有冲突,所以如果出现定义冲突的问题,可以尝试更换NDK的版本来解决

配置SO库
  1. 在android/app目录下创建CMakeList.txt文件(该文件的配置说明将在之后说明)
  2. 在android/app目录下创建libs目录,将api/core/lib目录下的fmod.jar文件拷贝到libs目录下
  3. 在android/app/src/main目录下分别创建cpp、jniLibs目录。注意:jniLibs目录名称一定不能写错,jniLIbs也必须创建在android/app/src/main目录下,在打包APK的时候,默认会将jniLibs目录下的so文件打包到APK中,如果该文件夹名称错误,就会导致APP运行的时候找不到动态运行库(.so文件)
  4. 在cpp目录下创建include目录,将fmod的api/core/inc目录下的文件拷贝到include目录中
  5. 在cpp目录下创建native-lib.cpp文件(之后会详细说明该文件的用途)

到这里,所有需要创建目录和文件,以及需要拷贝到项目中的文件都已经准备好,下面开始进行配置

  1. 配置build.gradle(Module:android.app)文件
  2. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_android_06,第6张


  3. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_jni_07,第7张

  4. 分别添加三处externalNativeBuild配置,在defaultConfig外面的是用来指定CMakeLists文件的路径,defaultConfig内部的是在执行CMake时的命令行参数,buildTypes内部的参数用来指定是用libfmod.so还是用libfmodL.so,fmod提供了调试环境和正式环境下对应的不同so文件
  5. dependencies增加依赖
  6. flutter golang 搜索引擎 flutter so库,flutter golang 搜索引擎 flutter so库_flutter_08,第8张

  7. CMakeList.txt配置说明
cmake_minimum_required(VERSION 3.10.2)

# Declares and names the project.

project("audioplayerjni")

# 定义LIB_FMOD变量,值为FMOD的so文件在项目的绝对路径
# CMAKE_SOURCE_DIR内置变量,值为CMakeList.tx的路径
# ANDROID_ABI内置,当前android设备的ABI类型
# 在build.gradle的buildTypes中传递的参数
set( LIB_FMOD ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libfmod${FMOD_LIB_SUFFIX}.so )

# 定义CPP_DIR,值为cpp目录的绝对路径
set( CPP_DIR ${CMAKE_SOURCE_DIR}/src/main/cpp )

# 指定头文件查找目录
include_directories( ${CMAKE_SOURCE_DIR}/src/main/cpp/include )

# 添加共享类型的链接库,名称为fmod,类型为SHARED,IMPORTED告诉cmake,该库是导入的
add_library( fmod SHARED IMPORTED )

# 设置fmod链接库的属性
# IMPORTED_LOCATION:本地so文件路径
# INTERFACE_INCLUDE_DIRECTORIES:头文件路径
set_target_properties(
        fmod PROPERTIES
        IMPORTED_LOCATION ${LIB_FMOD}
        INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/src/main/cpp/include
)

# 添加一个共享类型的链接库,与IMPORTED不同的是,该库是项目目录中的一个cpp文件
add_library(
        native-lib
        SHARED
        ${CPP_DIR}/native-lib.cpp
)

# 指定需要链接的库
target_link_libraries(
        native-lib
        fmod
)
使用
  1. 在MyApplication中加载c++库
class MyApplication : FlutterApplication() {
    init {
    	//native-lib是在CMakeLists.txt中定义的本地库的名称
        System.loadLibrary("native-lib")
    }

    override fun onCreate() {
        ...
    }
}
  1. 创建FmodAudioPlayer类
class FmodAudioPlayer {
       /**
        * A native method that is implemented by the 'native-lib' native library,
        * which is packaged with this application.
        * 定义方法,具体的实现在native-lib.cpp中
        */
       external fun play(path: String, type: Int, uuid: String)
       external fun stop(uuid: String)
       external fun isPlaying(uuid: String):Boolean
   }
  1. native-lib.cpp文件实现方法
/**
 * Java_com_xiaomajiaoyu_baby_FmodAudioPlayer_play方法名说明
 * Java固定开头
 * com.xiaomajiaoyu.baby包名
 * FmodAudioPlayer类名
 * play方法名
 * 都以_连接
 */
extern "C"
JNIEXPORT void JNICALL
Java_com_xiaomajiaoyu_baby_FmodAudioPlayer_play(JNIEnv *env, jobject thiz, jstring path_jstr,
                                            jint type, jstring uuid_jstr) {
     //调用fmod的播放音频的API
}

extern "C"
JNIEXPORT void JNICALL
Java_com_xiaomajiaoyu_baby_FmodAudioPlayer_stop(JNIEnv *env, jobject thiz, jstring uuid_jstr{
    //调用fmod的停止播放的API
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_xiaomajiaoyu_baby_FmodAudioPlayer_isPlaying(JNIEnv *env, jobject thiz, jstring uuid_jstr) {
    //调用fmod获取播放状态的API
}

至此,就已经完成了flutter项目集成fmod的库的工作,剩下的只需要在flutter端通过MethodChannel的通信方式,调用android远程的接口,再用远程接口调用FmodAudioPlayer中的native方法,就可完成fmod的使用。需要注意的一点,FmodAudioPlayer的接口调用都是在主线程,也就是UI线程上调用,为了不影响UI线程,需要将FmodAudioPlayer的接口调用放到子线程中,这样一来,如果native方法都是在不同线程中执行,就存在线程安全问题,这时候就需要用到IntentService,将FmodAudioPlayer接口的调用都放到IntentService中执行,IntentService可以即实现在子线程执行方法,同时也能保证方法的执行顺序。



https://www.xamrdz.com/mobile/42v1924626.html

相关文章: