简体   繁体   English

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

[英]How to add JNI (C/C++ native code) to existing Android Studio project

Like the title says - how to add native code to existing Android Studio project, without breaking the current project, including gradle and proguard settings?正如标题所说 - 如何在不破坏当前项目的情况下将本机代码添加到现有的 Android Studio 项目,包括 gradle 和 proguard 设置?

Since Android Studio 3.1 its possible easy way:从 Android Studio 3.1 开始,它可能是一种简单的方法:

1. Create cpp folder inside app\src\main . 1. 在app\src\main中创建cpp文件夹。

2. Create <YOUR_FILE_NAME>.cpp file in app\src\main\cpp path (eg native-lib.cpp) 2. 在app\src\main\cpp路径下创建<YOUR_FILE_NAME>.cpp文件(例如native-lib.cpp)

3. Add CMakeLists.txt file to app folder. 3. 将CMakeLists.txt文件添加到app文件夹。

In that file name of the library, .cpp file path and some other settings should be defined, eg (from new, empty Android Studio Project with C++ support):在该库的文件名中,应定义.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. Add to build.gradle (Module app) externalNativeBuild tag with reference to CMakeLists.txt into android section: 4. build.gradle (Module app) externalNativeBuild标签参考CMakeLists.txt添加到android部分:

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
}

5. Add to build.gradle (Module app) externalNativeBuild tag with cmake tag into defaultConfig section: 5. 将带有cmake标签的 build.gradle (Module app) externalNativeBuild标签添加到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
}
...

(example of "basic" build.gradle file also available in new, empty Android Studio project with C++ support) (“基本” build.gradle文件的示例也可用于支持 C++ 的新空 Android Studio 项目)

6. Resync Project with Gradle files 6. 使用 Gradle 文件重新同步项目

By clicking Sync Project通过单击同步项目工具栏上的同步项目按钮 in the toolbar.在工具栏中。 NB.注意。 In Android Studio 3,3, the icon is在 Android Studio 3,3 中,图标是工具栏上的 Android Studio 3.3 同步项目按钮 . .

Also, take a look at Official Tutorial .另外,看看 官方教程

PS.附言。 If files not shown in cpp folder:如果文件未显示在cpp文件夹中:

try File/Invalidate Caches & Restart as Thinh Vu mentioned in his comment.正如Thinh Vu在他的评论中提到的那样尝试File/Invalidate Caches & Restart

Follow this steps from your existing project:按照现有项目中的以下步骤操作:

1. Modify build.gradle (Module app) to look like this (a lot changes:): 1. 修改 build.gradle (Module app) 看起来像这样(很多变化:):

    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'
    }

You can copy/paste the above code and modify at least the values with "--value--" to match yours.您可以复制/粘贴以上代码并至少修改带有“--value--”的值以匹配您的值。

2. Modify build.gradle (Project) 2.修改build.gradle(项目)

where it says something like this:它说的是这样的:

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

to this:对此:

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

The number in my example 0.9.3 is the latest version of gradle-experimental to be found here .我示例中的数字0.9.3是最新版本的 gradle-experimental 可以在这里找到。 Eventually change your gradle version in gradle-wrapper.properties to the version recommended by Android Studio if you did not already.最终将 gradle-wrapper.properties 中的gradle版本更改为 Android Studio 推荐的版本(如果您尚未这样做)。

3. Move your proguard settings file 3.移动你的proguard设置文件

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

4. Add the call from java 4.添加java调用

like this像这样

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

changing to your needs.改变你的需要。 The example above loads the c-file (write it without the extension) - the same one declared in the gradle file, and calls the function my_jni, passing the application's Context, some byte array and some int, expecting that the functions returns a byte.上面的示例加载 c 文件(不带扩展名写入)——与 gradle 文件中声明的相同,并调用函数 my_jni,传递应用程序的上下文、一些字节数组和一些 int,期望函数返回一个字节.

5. Create the function in JNI: 5. 在 JNI 中创建函数:

Now the name of your function is highlighted in red - allow Android Studio to create it Create function... with clicking on the red lamp on the row.现在您的函数名称以红色突出显示 - 允许 Android Studio 创建它Create function...单击行上的红灯。 This creates the function in your c file and changes focus to it.这将在您的 c 文件中创建函数并将焦点更改到它。

Done完毕

Further reading here . 在这里进一步阅读。

Tips:尖端:

  • Take care to free everything you malloc , ReleaseByteArrayElements for every GetByteArrayElements and so on注意free所有你的mallocReleaseByteArrayElements为每个GetByteArrayElements等等

  • Take care how to properly return some dangerous values from C to Java, like arrays and Strings注意如何正确地将一些危险值从 C 返回到 Java,例如数组和字符串

There is an easy way now, just right-click on your module in Project explorer and click on Add C++ to the Module:现在有一个简单的方法,只需在 Project explorer 中右键单击您的模块,然后单击 Add C++ to the Module:

在此处输入图像描述

To see the structure of a code with JNI, create an empty project with C++.要使用 JNI 查看代码的结构,请使用 C++ 创建一个空项目。 File=>New=>New project=>Native C++.文件=>新建=>新建项目=>本机 C++。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM