1. 程式人生 > >[Android]NDK開發環境配置與JNI開發

[Android]NDK開發環境配置與JNI開發

本文的目標是實現NDK開發環境的配置以及學習JNI開發流程。

1.環境配置

本文的開發環境為win10 64位+Eclipse+Android ADT+NDK+CDT。

2.安裝:

這裡只介紹NDK和CDT的安裝。

2.2配置系統的環境變數,操作路徑為:高階系統設定–>環境變數–>找到PATH–>新建即可,如下圖所示:
這裡寫圖片描述

2.3為Eclipse新增NDK路徑,操作路徑為:Windows–>Preference–>NDK,如下圖所示:
這裡寫圖片描述

3.完成了第二步,接下來進行程式碼編寫

3.1新建一個安卓專案,並在專案的根目錄下新建jni資料夾,如下圖所示:
這裡寫圖片描述

3.2在string.pub.jni.test包下新建TestJni.java類,新增如下程式碼:

package string.pub.jni.test;

public class TestJni {
        public native boolean init();
        public native int add(int x , int y);
        public native void destory();
        }

3.3將上一步建立的類檔案拷貝到bin目錄下,然後從命令列介面cd到..\AJniDemo\bin目錄下執行javac TestJni.java,完成後可以看到在bin目錄下生成的TestJni.class檔案了。之後在..\bin目錄下按照包名的順序新建資料夾,路徑為..\bin\string\pub\jni\test,將TestJni.class拷貝到..\bin\string\pub\jni\test目錄下,在命令列介面執行javah -jni string.pub.jni.test.TestJni可以看到在..\bin目錄下生成了string_pub_jni_test_TestJni.h這個標頭檔案。將生成的標頭檔案拷貝到專案的jni目錄下,如下圖所示:
這裡寫圖片描述

3.4上一步生成了所需要的標頭檔案,這一步開始實現c++層的程式碼了。按照上一步新建圖中的檔案,然後右鍵專案–>Android Tools–>Add Native Support。所需要的程式碼如下:

//Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := TestJNI
LOCAL_SRC_FILES := string_pub_jni_test_TestJni.cpp
LOCAL_SRC_FILES += CAdd.cpp

include $(BUILD_SHARED_LIBRARY)
//Application.mk
APP_PROJECT_PATH := ${call my-dir}
APP_BUILD_SCRIPT=$(APP_PROJECT_PATH)/Android.mk
APP_MODULES := TestJNI

APP_ABI := armeabi armeabi-v7a x86
//CAdd.cpp
#include "CAdd.h"
CAdd::CAdd(){
}
CAdd::~CAdd(){
}
int CAdd::add(int x, int y){
return x+y;
}
//CAdd.h
#ifndef JNI_TEST_ADD
#define JNI_TEST_ADD
class CAdd{
public:
CAdd();
~CAdd();
int add(int x, int y);
};
#endif
//string_pub_jni_test_TestJni.cpp
#include <stdlib.h>
#include <stdio.h>
#include "CAdd.h"
#include "jni.h"

CAdd *pCAdd = NULL;
extern "C" {
JNIEXPORT jboolean JNICALL Java_string_pub_jni_test_TestJni_init
  (JNIEnv *env, jobject obj){
if(pCAdd==NULL){
pCAdd = new CAdd ;
}
return pCAdd!=NULL;
}

JNIEXPORT jint JNICALL Java_string_pub_jni_test_TestJni_add
  (JNIEnv *env, jobject obj, jint x, jint y){
jint res = -1;
if(pCAdd==NULL){
    pCAdd = new CAdd ;
res = pCAdd->add(x,y);
}else{
    res = pCAdd->add(x,y);
}
return res;
}

JNIEXPORT void JNICALL Java_string_pub_jni_test_TestJni_destory
  (JNIEnv * env, jobject obj){
if(pCAdd!=NULL){
delete pCAdd;
pCAdd=NULL;
}
}
}

3.5命令列介面下,在專案根目錄下執行:ndk-build,成功之後重新整理專案,就可以看到在Libs下面生成了.so檔案。如下圖所示:
這裡寫圖片描述

4.呼叫JNI方法:

4.1將3中生成的.so檔案拷貝到別的專案的libs資料夾下,然後新建下圖所示的包和類:
這裡寫圖片描述
4.2在TestJni.java中新增如下程式碼:

package string.pub.jni.test;

public class TestJni {
        public native boolean init();
        public native int add(int x , int y);
        public native void destory();
        }

4.3在其他地方呼叫JNI方法,如下所示:

import string.pub.jni.test.TestJni;

public class MainActivity extends Activity {

    static{
        System.loadLibrary("TestJNI");
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TestJni test=new TestJni();
        int ii=test.add(22, 2);
        Toast.makeText(getApplicationContext(), ""+ii, Toast.LENGTH_SHORT).show();
    }

以上,就是一個簡單的JNI開發例項。