Android JNI Learning (2) - "hello world" of actual combat JNI

 This series of articles are as follows:

Android JNI learning (1) - NDK and JNI basic
Android JNI learning (2) - "hello world" of actual JNI
Android JNI learning (3) - Java and Native call each other
Android JNI learning (4) - JNI Chinese API for common methods

 1. Environmental display

operating system:

 Android environment:

 NDK environment:

 Simulator:

2. The specific process of the traditional method

The specific process is as follows:

(1) Create a project

First create an Android project in Android Studio, the package name is gebilaolitou.ndkdemo.

(2) Create a tool class that references a local library

Then create a class for NDKTools

code show as below:

package gebilaolitou.ndkdemo;

public class NDKTools {

    public static native String getStringFromNDK();

}

(3) Modify the relevant UI display

Add id to the textview in the xml corresponding to MainActivity.
as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="gebilaolitou.ndkdemo.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

Then modify MainActivity and call the getStringFromNDK() method of NDKTools in it.

package gebilaolitou.ndkdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String text = NDKTools.getStringFromNDK();
        Log.i("gebilaolitou","text="+text);
        ((TextView)findViewById(R.id.tv)).setText(text);
    }
}

(4) Get the classes file

In Android Studio, click Make Project or Rebuild Project in Build to compile to obtain intermediate files. As shown below:

 After the compilation is complete, we can get the class file as shown below:

(5) Enter the corresponding directory

Click Terminal under Android Studio, then jump to NDKDemo/app/build/intermediates/classes/debug (where NDKDemo is the root directory of the project), and execute pwd in Terminal to confirm the directory.

(6) Get the .h file

Execute the following command javah -jni gebilaolitou.ndkdemo.NDKTools under NDKDemo/app/build/intermediates/classes/debug . If there is no problem, the gebilaolitou_ndkdemo_NDKTools.h file will be generated under NDKDemo/app/build/intermediates/classes/debug. As shown below:

 Its content is as follows:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class gebilaolitou_ndkdemo_NDKTools */

#ifndef _Included_gebilaolitou_ndkdemo_NDKTools
#define _Included_gebilaolitou_ndkdemo_NDKTools
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     gebilaolitou_ndkdemo_NDKTools
 * Method:    getStringFromNDK
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

(7) Add the corresponding .c file

Create a directory named jni under the main directory of the project, and then cut the .h file just now. Create a new c file in the jni directory. Name it ndkdemotest.c. At this point the project directory is as follows:

 (8) Write the ndkdemotest.c file

Negotiate ndkdemotest.c as follows:

#include "gebilaolitou_ndkdemo_NDKTools.h"

JNIEXPORT jstring JNICALL Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK
  (JNIEnv *env, jobject obj){
     return (*env)->NewStringUTF(env,"Hellow World,这是隔壁老李头的NDK的第一行代码");
  }

There is not much content, just two parts, the first part is to add the gebilaolitou_ndkdemo_NDKTools.h header file, and then implement the Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK function

(9) Add and write Android.mk file

Also in the jni directory, add an Android.mk file, the directory structure is as follows

 Also write the following content in the Android.mk file:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ndkdemotest-jni

LOCAL_SRC_FILES := ndkdemotest.c

include $(BUILD_SHARED_LIBRARY)

About the Android.mk language, I will write a separate article to explain it. Here I will focus on the content of the above code

  • LOCAL_PATH := $(call my-dir): Every Android.mk file must start with a definition. It is used to find source files in the development tree. The macro my-dir is provided by Build System. Returns the path to the directory containing Android.mk.
  • include $(CLEAR_VARS) : The CLEAR_VARS variable is provided by the Build System. And point to a specified GNU Makefile, which is responsible for cleaning up many LOCAL_xxx. For example LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES and so on. But not cleaning LOCAL_PATH. This cleanup is necessary because all compile control files are parsed and executed by the same GNU Make, whose variables are global. So after cleaning, the instant noodles can interact with each other.
  • LOCAL_MODULE := ndkdemotest-jni: The LOCAL_MODULE module must be defined to represent every module in Android.mk. Names must be unique and contain no spaces. The Build System will automatically add the appropriate prefixes and suffixes. For example, demo, to generate a dynamic library, generate libdemo.so. But please note: if the module name is defined as libabd, libabc.so will be generated. No more prefixes.
  • LOCAL_SRC_FILES := ndkdemotest.c: This line of code represents the C/C++ source code to be packaged. There is no need to list the header files, the build system will automatically find the dependent files for us. The default C++ source code extension is .cpp.
  • include $(BUILD_SHARED_LIBRARY): BUILD_SHARED_LIBRARY is a variable provided by Build System, pointing to a GUN Makefile Script. It is responsible for collecting all LOCAL_xxxxxxs since the last call to include $(CLEAR_VARS). and decide what type to compile

BUILD_STATIC_LIBRARY: Compile as a static library
BUILD_SHARED_LIBRARY: Compile as a dynamic library
BUILD_EXECUTABLE: Compile as a Native C executable
BUILD_PREBUILT: This module has been precompiled

PS: If Android.mk is not written here, the following questions will be prompted:

Error:Execution failed for task ':app:compileDebugNdk'.
> Error: Flag android.useDeprecatedNdk is no longer supported and will be removed in the next version of Android Studio.  Please switch to a supported build system.
  Consider using CMake or ndk-build integration. For more information, go to:
   https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile
   To get started, you can use the sample ndk-build script the Android
   plugin generated for you at:
   /Users/gebilaolitou/AndroidStudioProjects/JNIDemo/app/build/intermediates/ndk/debug/Android.mk
  Alternatively, you can use the experimental plugin:
   https://developer.android.com/r/tools/experimental-plugin.html
  To continue using the deprecated NDK compile for another 60 days, set 
  android.deprecatedNdkCompileLease=1523001628930 in gradle.properties

All in English, a simple translation is as follows:

错误:执行app:compileDebugNdk任务失败
错误:不再支持android.useDeprecatedNdk标志,并且将会在未来的Android Studio版本中删除这个标志。请切换到CMake构建系统或者ndk-build中集成。更多的信息请参考https://d.android.com/r/studio-ui/add-native-code.html#ndkCompile。您可以使用Android的示例ndk-build脚本在以下位置生成的插件:
/Users/gebilaolitou/AndroidStudioProjects/JNIDemo/app/build/intermediates/ndk/debug/Android.mk。另外,你也可以使用实验性插件https://developer.android.com/r/tools/experimental-plugin.html
如果你还想继续再使用已经被弃用的NDK编译60天,你需要再gradle.properties中设置android.deprecatedNdkCompileLease=1523001628930

Because of the above reasons, we need to set Android.mk

(10) Modify the corresponding configuration file

First check whether there is an NDK path in the local.properties file. If there is no NDK path, add the NDK path. For example, mine is as follows:

ndk.dir=/Users/debilaolitouLibrary/Android/sdk/ndk-bundle
sdk.dir=/Users/debilaolitouLibrary/Library/Android/sdk

Secondly, modify the content in build.gradle in the app module directory, as follows:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "gebilaolitou.ndkdemo"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk{

            moduleName "ndkdemotest-jni"
            abiFilters "armeabi", "armeabi-v7a", "x86"

        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        externalNativeBuild {
            ndkBuild {
                path 'src/main/jni/Android.mk'
            }
        }
        sourceSets.main {
            jni.srcDirs = []
            jniLibs.srcDirs = ['src/main/jniLibs']
        }
    }
}

In this way, there will be a so file (the so file has not been generated yet)

(11) Modify the reference class

Finally, add static initialization code in the NDKTools class, as follows:

public class NDKTools {

    static {
        System.loadLibrary("ndkdemotest-jni");
    }

    public static native String getStringFromNDK();
}

Finally, run it, as shown below

3. Problems related to traditional methods

When some students are running, they will report the following error:

Error:Execution failed for task ':app:compileDebugNdk'.
> Error: Your project contains C++ files but it is not using a supported native build system.
  Consider using CMake or ndk-build integration. For more information, go to:
   https://d.android.com/r/studio-ui/add-native-code.html
  Alternatively, you can use the experimental plugin:
   https://developer.android.com/r/tools/experimental-plugin.html

First, add a sentence after checking the gradle.properties file in your project

Android.useDeprecatedNdk=true 

Fourth, the so file in the traditional way

You may have doubts, where did the so go? When we usually use the so of the third-party sdk, we will paste and copy it into the project. However, in the whole process we mentioned above, the .so file did not appear. Then this Where did the .so go?

In fact, Android Studio automatically helps us put so into the apk, if we want to find it, we can find it, as shown below:

The above method is the traditional Android Studio mode, is there an easier way, yes, then let's continue to look at it

5. Demonstrate the process through the CMake tool demo

(1) First make sure you have CMake locally, let's look at SDK Tools

I saw the third CMake above, I don’t have it locally, so I want to install it

(2) Check the Include C++ Support check box.

In the Configure your new project section of the wizard, select the Include C++ Support checkbox.
As shown below:

There is a pitfall here, that is, many students said that I did not have the Include C++ Support check box. This is because of the "bug" designed by Android Studio. If you enlarge this dialog box, it will appear, because the general Android project It is not used, so when designing this, if it is not deliberately enlarged, it will be selectively "hidden", which is too JB pit.

Then go to the next step until the Customize C++ Support section

(3) Custom projects of Customize C++ Support

as follows:

There are three items in it

  • C++ Standard: C++ standard, use the drop-down list to select the C++ standard you want to use, and select Toolchain Default to use the default CMake settings.
  • Exceptions Support: Select this checkbox if you wish to enable support for C++ exception handling. If this checkbox is enabled, Android Studio will add the -fexceptions flag to the cppFlags of the module-level build.gradle file, which Gradle will pass to CMake.
  • Runtime Type Information Support: Select this checkbox if the developer wishes to support RTTI. If you enable this checkbox, Android Studio will add the -frtti flag to the cppFlags of the module-level build.gradle file, which Gradle will pass to CMake.

Finally click Finish.

(4) Check the Android directory

After Android Studio has finished creating a new project, open the Project window from the left side of the IDE and select the Android view. As shown in the image below, Android Studio will add the cpp and External Build Files groups:

This figure shows the developer's native source files and Android viewgroups for external build scripts.

PS: (This view does not reflect the actual file hierarchy on disk, but groups similar files together to simplify project navigation). If it is Project mode, it is as follows:

Then let's briefly introduce these two extra folders:

  • In the cpp folder: all native source files etc. build libraries belonging to the project can be found. For new projects, Android Studio creates a sample C++ source file native-lib.cpp and places it in the application module src/main/cpp/ directory. This sample code provides a simple C++ function stringFromJNI() that returns the string "Hello from C++"
  • In the External Build Files folder: build scripts for CMake or ndk-build can be found. Just like the build.gradle file instructs Gradle to build the application, CMake and ndk-build require a build script to know how to build native libraries. For new projects, Android Studio creates a CMake build script, CMakeLists.txt, and places it in the module root directory.

(5) Run the project directly

Let's run this project directly and see the result

 (6) Modify native-lib.cpp

At this time, we modify native-lib.cpp, and the content of native-lib.cpp is as follows:

Then run the project directly and see the result. as follows:

We see that the corresponding text has been modified

6. The principle behind the CMake tool demo

We saw it, we didn't do anything, and we automatically realized the implementation of C++. What is the principle behind it? Let's all think about it?

(1) The entrance of CMake

Since it can run, there must be an entrance, so where is this entrance?

First, let me tell you how I imagined it. First of all, when we click the run button in Android Studio, it executes Gradle for packaging, so how to implant CMake must be in the build of the project. .gradle has a corresponding entry.

Through the above thinking, what can we get by inference? Yes, it is similar to this kind of operation, which is generally implemented in build.gradle, because currently Android Studio is implemented through Gradle

Then let's take a look at the code in its build.gradle, as follows:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "gebilaolitou.cmakendkdemo"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }
    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:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}

It is similar to the projects we usually build, except that there is an extra piece of content, externalNativeBuild. Here we focus on externalNativeBuild

(二) externalNativeBuild

We saw in build.gradle that externalNativeBuild is used in two places, one is inside defaultConfig and the other is outside defaultConfig.

  • The cmake in externalNativeBuild outside defaultConfig specifies the path of CMakeList.txt (under this project, it is in the same directory as build.gradle).
  • The cmake in externalNativeBuild in defaultConfig mainly fills in the command parameters of CMake. That is, the parameters in arguments are finally converted into an executable CMake command, which can be found in app/externalNativeBuild/cmake/debug/{abi}/cmake_build_command.txt.

The path location is as shown below:

 The content is as follows:

arguments : 
-H/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app
-B/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app/.externalNativeBuild/cmake/debug/x86
-DANDROID_ABI=x86
-DANDROID_PLATFORM=android-23
-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=/Users/gebilaolitou/Desktop/codeLib/CMakeNDKDemo/app/build/intermediates/cmake/debug/obj/x86
-DCMAKE_BUILD_TYPE=Debug
-DANDROID_NDK=/Users/gebilaolitou/Library/Android/sdk/ndk-bundle
-DCMAKE_CXX_FLAGS=
-DCMAKE_TOOLCHAIN_FILE=/Users/gebilaolitou/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
-DCMAKE_MAKE_PROGRAM=/Users/gebilaolitou/Library/Android/sdk/cmake/3.6.4111459/bin/ninja
-GAndroid Gradle - Ninja
jvmArgs : 

For more command parameters and meanings that can be filled in, please refer to the Android NDK-CMake documentation

Ok, since CMakeLists.txt is mentioned above, let's take a look at CMakeLists.txt.

(三) CMakeLists.txt

The CMakeLists.txt file mainly defines which files need to be compiled, and the relationship with other libraries, etc. Let's take a look at the content of CMakeLists.txt in our project:

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

# 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} )

Many of the above are comments. Let's remove the comments and come up with a "simplified version" as follows:

cmake_minimum_required(VERSION 3.4.1)

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 )


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 )

target_link_libraries( # Specifies the target library.
                       native-lib

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

CMakeLists.txt we see here is mainly divided into four parts, let's look at it in turn

cmake_minimum_required(VERSION 3.4.1): Specify the minimum version of CMake
add_library: Create a static or dynamic library and provide its associated source file path. Developers can define multiple libraries, and CMake will automatically build them. Gradle can automatically package them into the APK.

  • The first parameter - native-lib: is the name of the library
  • The second parameter - SHARED: is the category of the library, whether it is dynamic or static
  • The third parameter - src/main/cpp/native-lib.cpp: is the path of the source file of the library

find_library: Find a precompiled library and save it as a variable. Since CMake will include system libraries when searching the library path, and CMake will check the names of its own previously compiled libraries, developers need to ensure that the names of libraries added by developers are unique.

  • The first parameter - log-lib: set the name of the path variable
  • The first parameter - log: specify the name of the NDK library, so that CMake can find this library

target_link_libraries: Specify CMake to link to the target library. Developers can link multiple libraries. For example, developers can define library build scripts here, and precompile third-party libraries or system libraries.

  • The first parameter - native-lib: the specified target library
  • The first parameter - ${log-lib}: link the target library to the log library in the NDK

This is actually the most basic CMakeLists.txt. In fact, CMakeLists.txt can be very powerful, such as custom commands, search files, header file inclusion, setting variables, and so on. Here I recommend CMake's official website documentation, but it is in English, which is not easy to read. You can refer to the Chinese CMake manual .

After analyzing CMakeLists.txt above, we have a general idea of ​​the overall construction process of CMake, so let's take a look:

(4) The operation process of CMake

  1. Gradle calls external build script CMakeLists.txt
  2. CMake compiles the C++ source file native-lib.cpp into a shared object library according to the command of the build script, and names it libnative-lib.so, and Gradle will then package it into the APK
  3. At runtime, the application's MainActivity will use System.loadLibrary() to load the native library. The application is to use the native function stringFromJNI() of the library.

PS: One thing to note here is: Instant Run is not compatible with native projects.

If you want to see whether Gradle has packaged the native library into the APK, you can use Analyze APK to detect it.

7. Application of CMake

When we do daily needs, we often encounter a problem, that is, to add a C library to an existing project, so that we cannot use CMake through the above creation process. So what to do?

In fact, it doesn't matter, CMake also provides such a function, now we go back to the first demo above, delete all the codes related to NDK, after deletion, its directory is as follows:

(1) Create source files

That is, create a new directory under the main directory, we will call it cpp. Then create a C++ Source File in that directory (right click on the directory you just created and select New > C/C++ Source File). We named it native-lib.

After creation, the directory is as follows:

(2) Create a CMake build script

Since there is currently no CMake build script for this project, we need to create one ourselves and include the appropriate CMake commands. The CMake build script is a plain text file, and the name must be CMakeLists.txt.

To create a plain text file that can be used as a CMake build script, follow these steps:

  1. Open the Project pane from the left side of Android Studio and select the Project view from the drop-down menu.
  2. Right-click on the module's root directory and select New --> File.
  3. PS: This location is not fixed, the location can be arbitrary, but when configuring the build script, you need to write this location into the build script
  4. Enter CMakeLists.txt as the file and click OK

After creation, the directory is as follows:

 (3) Write data to the CMake script file

This piece has been explained above, so I won’t go into details. The content is as follows:

cmake_minimum_required(VERSION 3.4.1)

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 )

find_library( # Defines the name of the path variable that stores the
              # location of the NDK library.
              log-lib

              # Specifies the name of the NDK library that
              # CMake needs to locate.
              log )
              

target_link_libraries( # Specifies the target library.
                       native-lib

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

(4) Associate Gradle with the native library

To link Gradle to a native library, provide a path to a CMake or ndk-build script file. When building an application, Gradle runs CMake or ndk-build as dependencies and packages shared libraries into APKs. Gradle still uses build scripts to know which files to add to the Android project.

If the native file does not have a build script yet, a CMake build script needs to be created.

There are two ways to link to the native library, one is through Android Studio, and the other is manual. In fact, the things behind it are the same, so let’s explain them one by one:

1. Realized through Android Studio

  1. Open the Project pane from the left side of the IDE and select the Android view
  2. Right-click on the module you want to link to the native library (in our case, the app module) and select Link C++ Project with Gradle from the menu. As shown below
  3. Select CMake in the drop-down menu. Use Project Pat to specify the `CMakeLists.txt` script file just now for the external CMake project
  4. click OK

2. Manual implementation

To manually configure Gradle to link to a native library, you need to add an externalNativeBuild{} block to your module-level build.gradle file and configure it with cmake {}.

code show as below:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "gebilaolitou.ndkdemo"
        minSdkVersion 19
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

    }

    externalNativeBuild {
        cmake {
            path 'CMakeLists.txt'
        }
    }
}

(5) Write native-lib.cpp

This piece is very simple, as follows:

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

extern "C"
JNIEXPORT jstring

JNICALL
Java_gebilaolitou_ndkdemo_NDKTools_getStringFromNDK(
        JNIEnv *env, jobject /* this */) {
    std::string hello = "(*^__^*) 嘻嘻……~Hello from C++ 隔壁老李头";
    return env->NewStringUTF(hello.c_str());
}

Then add a reference to NDKTools.java, as follows:

package gebilaolitou.ndkdemo;


public class NDKTools {

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

    public static native String getStringFromNDK();
}

Then run it directly, and the result is as follows:

 8. Introduction to using the experimental-plugin plug-in

We have a troublesome thing when using NDK development, which is to write Android.mk and Android Studio's plug-in gradle-experimental is used to solve this problem. So using the gradle-experimental plugin can be used for NDK development without writing .mk files.

gradle-experimental is an experimental project of Android Studio. It is a plug-in based on gradle. It is mainly used to automate the configuration of NDK. There is no need to write Android.mk by yourself. It is also more friendly to debugging NDK projects, but it is no longer supported. See Experimental Plugin User Guide for details

Note to experimental Android plugin users: The experimental plugin will no longer be supported after version 0.11.0 (released October 25, 2017). That's because the experimental plugin is designed around a Software Component Model that Gradle announced they will no longer support (read their blog post here). Gradle has backported many features from the component model, which are now available with Android plugin 3.0.0, such as variant-aware dependency resolution, and api and implementation dependency configurations. Gradle is working on backporting built-in support for compiling C/C++ code, and the Android plugin will integrate that support when it becomes available. Until then, you can either keep using experimental plugin 0.11.0 with Android Studio 3.0 or later, or migrate to Android Studio's support for using external native build tools.

A simple translation is as follows:

Note to users who use the experimentalAndroid plugin: After 0.11.0 released on October 25, 2017, we will no longer support the experimental plugin. Because Gradle no longer supports the design of experimental plugins that rely on the Software Component Model (via their blog). In version 3.0.0 of the Gradle Android plugin, many features in the build model are now supported. Examples include variant-aware dependency resolution and api and implementation dependency configurations. Gradle now supports built-in support for compiling C/C++ code, and the Android plugin will integrate this support when it becomes available. In the meantime, you can continue to use the experimental plugin of Android Studio 3.0 or later, or use the external native build tools supported by Android Studio.

おすすめ

転載: blog.csdn.net/Jason_Lee155/article/details/132248411