如何将JNI(C / C ++本机代码)添加到现有的Android Studio项目中

时间:2017-07-15 12:22:57

标签: android java-native-interface

如标题所述 - 如何在不破坏当前项目的情况下(如gradle和proguard设置)将本机代码添加到现有Android Studio项目中?

3 个答案:

答案 0 :(得分:15)

自Android Studio 3.1以来,其可能的简便方法是:

1。在cpp路径上创建app\src\main文件夹。

2。在<YOUR_FILE_NAME>.cpp路径中创建app\src\main文件(例如native-lib.cpp)

3。将CMakeList.txt文件添加到app文件夹中。

在该库的文件名中,应定义.cpp文件路径和其他一些设置,例如(来自具有C ++支持的新的空Android Studio项目):

# 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 )
                          ^^^^^^^^^^^^^^
                          YOUR_CPP_FILE_NAME

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

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

4。将参考externalNativeBuild的{​​{1}}标签添加到build.gradle(模块应用)CMakeLists.txt部分:

android

5。将带有android { compileSdkVersion 26 defaultConfig { ... } buildTypes { ... } externalNativeBuild { <--- these lines should be added cmake { <--- these lines should be added path "CMakeLists.txt" <--- these lines should be added } <--- these lines should be added } <--- these lines should be added } 标签的externalNativeBuild标签添加到build.gradle(模块应用)中的cmake部分:

defaultConfig

(“基本” ... defaultConfig { applicationId "<YOUR_APP_ID>" minSdkVersion 26 targetSdkVersion 26 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { <--- these lines should be added cmake { <--- these lines should be added cppFlags "" <--- these lines should be added } <--- these lines should be added } <--- these lines should be added } ... 文件的示例在具有C ++支持的新的空Android Studio项目中也可用)

6。使用Gradle文件重新同步项目

通过点击工具栏中的同步项目Sync Project button on Toolbar。注意!在Android Studio 3.3中,图标为 Android Studio 3.3 Sync Project button on Toolbar

还要看一下Official Tutorial

答案 1 :(得分:6)

从现有项目中执行以下步骤:

1。修改build.gradle(模块应用程序)看起来像这样(很多变化!):

    apply plugin: 'com.android.model.application'

    model {
        android.signingConfigs {
            create ("myConfig") {
                keyAlias '--your-key-alias--'
                keyPassword '--key-password--'
                storeFile file('--/path/to/keystore.jks--')
                storePassword '--store-password--'
            }
        }
        android {
            compileSdkVersion 25
            buildToolsVersion '25.0.2'

            defaultConfig {
                applicationId "--your.app.name--"
                minSdkVersion.apiLevel 19
                targetSdkVersion.apiLevel 25
                versionCode 1
                versionName "1.0"
            }
            buildTypes {
                release {
                    minifyEnabled true
                    proguardFiles.add(file('proguard-android-optimize.txt'))
                    proguardFiles.add(file('proguard-rules.pro'))
                    signingConfig = $("android.signingConfigs.myConfig")
                }
            }
            ndk {
                moduleName "--c-file--"
                ldLibs.addAll(["android", "log"])
            }

        }
        android.dexOptions {
            javaMaxHeapSize "2048m"
        }
    }

    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:25.3.1'
    }

您可以复制/粘贴上述代码,并使用“--value--”修改至少与您匹配的值。

2。修改build.gradle(Project)

它说的是这样的:

dependencies {
    classpath 'com.android.tools.build:gradle:2.3.3'
}

到此:

dependencies {
    classpath 'com.android.tools.build:gradle-experimental:0.9.3'
}

我的示例 0.9.3 中的数字是要找到的最新版gradle-experimental here。最终将 gradle-wrapper.properties 中的gradle版本更改为Android Studio推荐的版本(如果您尚未安装)。

3。移动您的proguard设置文件

proguard-android-optimize.txtapp/proguard-android-optimize.txt

4。添加来自java的调用

像这样

static {
    System.loadLibrary("--c-file--");
}
private native byte my_jni(Context context, byte[] mByte, int i);

改变您的需求。上面的例子加载了c文件(没有扩展名写入) - 在gradle文件中声明的相同,并调用函数my_jni,传递应用程序的Context,一些字节数组和一些int,期望函数返回一个字节

5。在JNI中创建函数:

现在,您的功能名称以红色突出显示 - 允许Android Studio通过单击行上的红色指示灯创建它Create function ...。这会在c文件中创建函数并将焦点更改为它。

完成

进一步阅读here

提示:

  • 谨慎对待free mallocReleaseByteArrayElements所有GetByteArrayElements的所有内容,等等

  • 注意如何正确地将一些危险的值从C返回到Java,如数组和字符串

答案 2 :(得分:0)

要使用 JNI 查看代码的结构,请使用 C++ 创建一个空项目。文件=>新建=>新项目=>本机C++。