版本信息
Android Studio:
- Android Studio 3.2.1
- Build #AI-181.5540.7.32.5056338, built on October 9, 2018
- JRE: 1.8.0_152-release-1136-b06 amd64
- JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
- Windows 7 6.1
新建一个包含 C/C++ 支持的工程
- 新建一个新工程
- 命名工程,并设置工程目录,勾选 Include C++ support 选项
- 配置目标平台,此处选择 API26: Android 8.0 (Orea)
- 选择一个Activity
- 命名Activity
- 完成配置
- 查看代码
在 MainActivity.java 中可以看到系统默认添加的 native 接口: public native String stringFromJNI();
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNI());
}
/**
* A native method that is implemented by the 'native-lib' native library,
* which is packaged with this application.
*/
public native String stringFromJNI();
}
与之对应的是 $PROJECT\app\src\main\cpp\native-lib.cpp 文件,及 C 接口文件,其实现如下所示
#include <jni.h>
#include <string>
extern "C" JNIEXPORT jstring JNICALL
Java_com_example_administrator_jnitest_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
该函数的作用是返回一个字符串: Hello from C++
- 添加 NDK, CMake, LLDB
打开 File -> Settings -> Appearance & Behavior -> System Settings -> Android SDK -> SDK Tools
在其中勾选 CMake, LLDB, NDK
然后点击 Apply ,随后 Android Studio 就会开始下载相应的插件,等待下载完成自动解压安装
- 构建工程
点击 Build -> Make Project 开始构建,构建完成后即可在左侧栏里的 Project 分组下的 app -> build -> intermediates -> cmake -> debug -> obj 下看到编译好的各版本的库文件
- 点击 Run -> Run ‘app’ 编译并运行代码可以看到
向工程中添加新的 C/C++ 文件,生成库文件
- 添加 java 文件
首先在 app -> src -> java -> com.example.administrator.jnitest 下新建一个 class 文件,此处命名为 MyJNITest
- 在 com.example.administrator.jnitest 右击 -> new -> Java Class, 如下图
- 命名 java 文件
- 在新加入的Class文件中添加一个新方法,用于获取一个字符串
package com.example.administrator.jnitest;
public class MyJNITest {
// 读取一个字符串
public native String getCString();
}
注意:定义方法时,需要使用 native 关键字
- 生成 C/C++ 头文件
打开 Terminal ,定位到 $PROJECT\app\src\main\java 目录,执行以下命令
javah -d ../cpp com.example.administrator.jnitest.MyJNITest
执行成功后将会在 $PROJECT\app\src\main\cpp 目录下生成 .h 文件
- 在项目中添加 C/C++ 文件
命名新加入的 C/C++ 文件为 JNIHello.cpp
注意:需要手动添加尾缀
向新加入的 JNIHello.cpp 文件中添加 C/C++ 代码
#include "com_example_administrator_jnitest_MyJNITest.h"
JNIEXPORT jstring JNICALL
Java_com_example_administrator_jnitest_MyJNITest_getCString(JNIEnv *env, jobject instance)
{
return env->NewStringUTF("JNI hello, this is a message from c code");
}
- 修改 CMakeList.txt 文件,生成库文件
- 在已有的 add_library 之后添加新的 add_library
add_library( jnihello SHARED src/main/cpp/JNIHello.cpp )
- 在 find_library 中添加新的 library
find_library( # Sets the name of the path variable.
log-lib
jnihello
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
- 在 target_link_libraries 中添加新的 library
target_link_libraries( # Specifies the target library.
native-lib
jnihello
# Links the target library to the log library
# included in the NDK.
${log-lib} )
点击 Build -> ReBuild Project 进行编译,编译完成后即可看到生成的库文件
库文件路径:$PROJECT\app\build\intermediates\cmake\debug\obj
使用生成的库文件
- 在 MyJNITest.java 中添加语句,加载库文件
package com.example.administrator.jnitest;
public class MyJNITest {
static {
System.loadLibrary("jnihello");
}
public native String getCString();
}
注意:库名称是在 CMakeList.txt 文件中填写的名称,并且是大小写敏感的
- 在项目中使用 getCString() 方法
- 在界面中添加 button 和 textView ,然后在MainActivity.java中
setContentView(R.layout.activity_main);
之后添加代码
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TextView text_view = (TextView) findViewById(R.id.textView);
text_view.setText(new MyJNITest().getCString());
}
});
编译运行,点击 button 按钮,即可看到 C/C++ 代码输出的字符串