初學JNI(一)環境配置及調用流程

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;

相關文章
相關標籤/搜索