Android Studio 基于cmake 引入so库

筅森魡賤 提交于 2020-02-28 09:38:05

1. 搭建环境

环境变量:      
sudo apt-get remove openjdk*      
export JAVA_HOME=/opt/java/jdk1.8.0_211
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export NDK=/opt/java/android-ndk-r13b
export ANDROID_SDK=/opt/Sdk
export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools


export ANDROID_SDK=/opt/Sdk
export PATH=.:${JAVA_HOME}/bin:$PATH:$NDK:$ANDROID_SDK/platform-tools:$ANDROID_SDK/tools

export CC=/opt/java/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
echo $CC         #编译arm 下执行gcc
export CFCAGS="--sysroot=/opt/java/android-ndk-r13b/platforms/android-21/arch-arm"
                 #参数  指定编译头文件

$CC $CFCAGS -fPIC -shared -o libTest.so hello.c -I.     # 生成 arm 平台下 的动态库libTest.so

  2.1 新建android工程, Include C++ Support
   2.2. 拷贝so 库到指定 目录 下   库名:libTest.so


    2.3. native-lib.cpp 中 调用 so库函数

 Java :

public native String stringFromJNI();

native-lib.cpp

#include <jni.h>
#include <string>

#include <android/log.h>
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "JNI", __VA_ARGS__)

// c++ 中调用 c ,必须 要  extern "C"
extern "C" {
   extern jint test();
}


extern "C"
JNIEXPORT jstring

JNICALL
Java_dn_denganzhi_com_myapplication_MainActivity_stringFromJNI(
        JNIEnv *env,
        jobject /* this */) {


       jint r=  test();
        LOGE("hello ... jni--%d",r);

    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());


}


    2.4. 修改 CMakeLists.txt指定编译的时候 链接 libTest.so 库

 

# 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.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-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 )

# 设置一个变量
# CMAKE_CXX_FLAGS    c++的参数,会传递给编译器
# CMAKE_C_FLAGS      c
# 编译的时候传递参数需要连接so
# 动态库生成可执行程序的时候链接:
#  3.gcc main.c -o main -I. -L. -lsy : 生成可执行程序
#  -L 指定动态库的路径  libTest.so
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}")


# 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.


# libTest.so  去掉 lib .so ,编译有2个库
target_link_libraries( # Specifies the target library.
                       native-lib
                       Test
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

 2.5.  gradle配置   abiFilters生成架构库

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "dn.denganzhi.com.myapplication"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
                abiFilters "armeabi-v7a"
            }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

 

  2.6. 加载库, 调用native方法运行

static {
    System.loadLibrary("Test");
    System.loadLibrary("native-lib");
}

 

 

 注意:
在4.4以上,如果load一个动态库,需要先将这个动态库的依赖的其他动态库load进来

6.0以下, System.loadLibrary  不会自动为我们加载依赖的动态库
6.0以上,System.loadLibrary  会自动为我们加载依赖动态库

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!