使用Android Sutdio創建一個JNI程序基本步驟如下:
- 新建一個Android工程
- 生成.c頭文件
- 編寫實現native方法功能的cpp文件
- NDK安裝與配置
- 運行程序
新建一個Android工程
示例中,我新建了一個名爲LearnJni的Android工程。
project結構如下圖:
在MainActivity中編寫示例代碼如下:
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("myjni");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView textView = (TextView) findViewById(R.id.text_view);
textView.setText(getJniMessage());
}
public native String getJniMessage();
}
在靜態初始化塊中,我們調用System.loadLibrary("myjni")
來加載下面我們將會命名爲“myjni”的jni庫文件。並在程序中定義並使用了getJniMessage()
本地方法。
生成.c頭文件
使用Android Studio自帶的Terminal或你計算機系統的Terminal,將當前目錄切換到<Project>\app\src\main\java
下。然後執行如下命令:
執行過該命令後,將在<Project>\app\src\main\
目錄下創建一個名爲jni的文件夾,並在其中生成與MainActivity對應的c頭文件。執行完該命令後的project結構如下:
生成的.c頭文件內容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_sunxiaodong_learnjni_MainActivity */
#ifndef _Included_com_example_sunxiaodong_learnjni_MainActivity
#define _Included_com_example_sunxiaodong_learnjni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_sunxiaodong_learnjni_MainActivity
* Method: getJniMessage
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_sunxiaodong_learnjni_MainActivity_getJniMessage
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
編寫實現native方法功能的cpp文件
在<Project>\app\src\main\jni
下,新建一個cpp文件。將上一步生成的.c頭文件中的內容,拷貝到該cpp文件中。並根據具體需要的功能,實現相應native方法。示例中,我新建了一個名爲MyJniMessage.cpp的文件,具體實現內容如下:
//
// Created by sunxiaodong on 16/6/14.
//
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
#ifndef LOG_TAG
#define LOG_TAG "MY_JNI_LOG"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
#endif
/* Header for class com_example_sunxiaodong_learnjni_MainActivity */
#ifndef _Included_com_example_sunxiaodong_learnjni_MainActivity
#define _Included_com_example_sunxiaodong_learnjni_MainActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_example_sunxiaodong_learnjni_MainActivity
* Method: getJniMessage
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_example_sunxiaodong_learnjni_MainActivity_getJniMessage
(JNIEnv *env, jobject jObj) {
LOGE("jni輸出的log");
return (*env).NewStringUTF("我的第一個Jni");
}
#ifdef __cplusplus
}
#endif
#endif
作爲示例,getJniMessage()
方法的native實現很簡單,僅輸出一條log,並創建一個字符串。
通過上面步驟,我們Jni示例程序的編寫已經完成,接下來,執行“Build->Make Project”,如果你之前沒有安裝NDK,則會有以下“Messages Gradle Build”提示:
Error:Execution failed for task ':app:compileDebugNdk'.
> NDK not configured.
Download the NDK from http://developer.android.com/tools/sdk/ndk/.Then add ndk.dir=path/to/ndk in local.properties.
接下來,下載安裝NDK,並進行相關配置。
NDK安裝與配置
進入SDK Manager,按下圖所示,安裝NDK。
在local.properties中,指定ndk路徑。
在<Project>\app\build.gradle
文件中,添加ndk配置。
以上配置代碼指定的so庫名稱爲myjni,鏈接時使用到的庫,及最終輸出指定三種abi體系結構下的so庫。
完成如上的NDK的安裝和配置,再次執行“Build->Make Project”,則可能會有以下“Messages Gradle Build”提示:
如果出現該錯誤,則gradle.properties中添加android.useDeprecatedNdk=true。
執行“Build->Make Project”成功後,會在<Project>\app\build\intermediates\
下生成如下.so文件:
運行程序
運行該Android示例程序後,會輸出一條如下log:
程序運行後,界面展示如下: