1.搭建環境html
安裝Cygwin(Cygwin是在Windows平臺下模擬Linux環境的工具。)java
安裝NDK http://developer.android.com/tools/sdk/ndk/index.htmlandroid
配置環境變量:ios
1.1.使用Cygwin提供的命令行工具,使用 cd ..命令回到home路徑windows
1.2.進入/cygdrive路徑,找到本身NDK的安裝路徑,而後複製當前命令行顯示的完整路徑app
1.3.在Cygwin的etc路徑下找到profile文件,在其中的Path中添加上面複製的完整路徑,使用冒號分隔。工具
PS:在ndk-r7版本之後,再也不須要安裝Cygwin,能夠在windows環境下直接使用ndk-build進行交叉編譯編譯。須要在環境變量中配置NDK的路徑,以下:ui
在系統變量中新建:spa
變量名:NDK_HOME命令行
變量值:D:\Develop\android-ndk
在Path中添加:
%NDK_HOME%,使用分號分隔
在命令提示符中執行ndk-build,若是出現如下內容,則配置環境變量成功:
Android NDK: Could not find application project directory !
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.
D:\Develop\android-ndk\build/core/build-local.mk:130: *** Android NDK: Aborting
. Stop.
2.調用JNI的流程
2.1.在Java中定義native方法,該方法須要由C\C++來實現,例如:
public native String helloFromJNI();
2.2.在項目路徑下創建jni文件夾
2.3.在jni路徑下創建C\C++文件
2.4.在C\C++文件中定義對應的要事先的方法,須要導入jni.h頭文件
2.5.編寫Android.mk文件(能夠在NDK的docs路徑下找到ANDROID-MK.html,在第75行能夠找到實例代碼,複製便可),以下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.c
LOCAL_LDLIBS+=-llog
include $(BUILD_SHARED_LIBRARY)
Android.mk文件中,各行的解釋:
2.5.1.
LOCAL_PATH := $(call my-dir)
記錄Android.mk的文件位置,其中call my-dir,獲得絕對路徑2.5.2.
include $(CLEAR_VARS)
初始化參數信息
CLEAR_VARS 清空上次參數信息2.5.3.
LOCAL_MODULE := Hello
交叉編譯後,生成的可執行文件名稱2.5.4.
LOCAL_SRC_FILES := Hello.c
參與交叉編譯的源文件,須要多個源文件時,使用空格分隔2.5.5.
include $(BUILD_SHARED_LIBRARY)
指定交叉編譯後,生成的文件類型
BUILD_SHARED_LIBRARY-動態連接庫
BUILD_STATIC_LIBRARY-靜態連接庫
2.6.使用Cygwin命令行,進入jni目錄,使用ndk-build命令進行交叉編譯(ndk-r7及以上版本不須要使用Cygwin,直接在項目路徑下使用ndk-build命令便可進行交叉編譯),生成.so文件
2.7.在Java代碼中使用靜態方法調用編譯生成的庫文件,以下:
static {
System.loadLibrary("Hello");
}
2.8.調用native方法,實現JNI調用
3.C\C++中方法的命名
在Java代碼中定義的native方法以下:
public native String helloFromJNI();
則在C\C++代碼中須要命名爲:
jstring JNICALL Java_com_chen_jni_demo_MyActivity_helloFromJNI
4.方便生成方法名的方式
進入到工程的bin路徑下(jdk1.7則進入src路徑),使用javah命令生成.h頭文件:
javah com.chen.jni.demo.MyActivity
生成的.h文件內容以下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_chen_jni_demo_MyActivity */#ifndef _Included_com_chen_jni_demo_MyActivity
#define _Included_com_chen_jni_demo_MyActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_chen_jni_demo_MyActivity
* Method: helloFromJNI
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_chen_jni_demo_MyActivity_helloFromJNI
(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif
將該文件複製到jni路徑下,在C\C++代碼中使用
#include "com_chen_jni_demo_MyActivity.h"
將該文件包含進去。
此時,方法名能夠直接從.h文件中複製
JNIEXPORT jstring JNICALL Java_com_chen_jni_demo_MyActivity_helloFromJNI
(JNIEnv *, jobject)
5.在C\C++中使用Log輸出日誌
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
在C\C++文件彙總,使用以上代碼能夠調用Log進行輸出,此外,還必須在Android.mk文件中添加如下內容:
LOCAL_LDLIBS+=-llog
6.使用C++來實現JNI調用
不一樣於使用C代碼來實現JNI調用,使用C++實現調用時,還須要在jni路徑下編寫Application.mk文件,內容以下:
APP_ABI:=armeabi
APP_STL := gnustl_static
此時Android.mk文件中的內容以下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := Hello
LOCAL_SRC_FILES := Hello.cpp
LOCAL_LDLIBS+=-llog
include $(BUILD_SHARED_LIBRARY)
此時,就能夠在*.cpp文件中使用
#include <iostream>using namespace std;