Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Eclipse下的Android JNI 開發

Eclipse下的Android JNI 開發

編輯:關於Android編程

1 創建Android工程

首先建立一個名為AndroidJniTest的Android工程,包名默認為com.example.androidjnitest,src目錄下自動創建MainActivity.java。

\

2 設計JNI接口

創建新的文件包com.example.jni,並在改包下新建一個TestJNI.java的類。

\

打開TestJNI.java,我們將在這個文件裡創建一個JNI接口類,該Java類提供一個加法運算的接口:

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

注意,這裡的函數聲明要加上native關鍵字。

3 編譯JNI

將TestJNI.java文件復制到工程的bin目錄下,在終端中進入該工程的bin目錄,輸入javac TestJNI.java,這時會生成一個TestJNI.class文件。

\

\

在bin文件夾下,如果沒有則創建目錄:/com/example/jni,並把TestJNI.class復制到/bin/com/example/jni目錄下。然後在終端裡進入工程的bin目錄,輸入javah -jni com.example.jni.TestJNI,此時會生成一個com_example_jni_TestJNI.h文件。<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+IDxpbWcgc3JjPQ=="/uploadfile/Collfiles/20150212/2015021208583683.png" alt="\">

com_example_jni_TestJNI.h文件就是對應於上面定義的Java接口的C/C++頭文件。打開這個文件,可以看到系統已經為我們自動完成了接口函數的聲明:

\

這三個函數分別對應於JNI的三個接口函數,命名方式只是在前面加上了Java包名。

4 用C/C++實現JNI

有了JNI的C/C++頭文件,就可以在C層實現JNI接口了。首先在工程目錄下創建一個jni目錄,這個目錄就是專門用來放C/C++代碼的。把com_example_jni_TestJNI.h文件復制到jni目錄下,並在這裡創建一個com_example_jni_TestJNI.cpp文件。

由於我想用C++來實現JNI,所以上面兩個文件我只是用來作為動態鏈接庫的接口,具體的實現我希望放在一個類裡面來完成,因此我再添加兩個文件:Add.h和Add.cpp。

\

下面我們就來實現CAdd類和JNI接口。首先實現CAdd類:

CAdd.h

#ifndef JNI_TEST_ADD
#define JNI_TEST_ADD
class CAdd{
public:
CAdd();
~CAdd();
int add(int x, int y);
};
#endif


CAdd.cpp

#include "Add.h" 
CAdd::CAdd(){ 
}
CAdd::~CAdd(){ 
}
int CAdd::add(int x, int y){
return x+y;
}

然後我們來寫com_example_jni_TestJNI.cpp,實現JNI:

#include 
#include 
#include "Add.h"
 
CAdd *pCAdd = NULL;
 
JNIEXPORT jboolean JNICALL Java_com_example_jni_TestJNI_init
  (JNIEnv *env, jobject obj){
if(pCAdd==NULL){
pCAdd = new CAdd ;
}
return pCAdd!=NULL;
}
 
JNIEXPORT jint JNICALL Java_com_example_jni_TestJNI_add
  (JNIEnv *env, jobject obj, jint x, jint y){
jint res = -1;
if(pCAdd!=NULL){
res = pCAdd->add(x,y);
}
return res;
}
 
JNIEXPORT void JNICALL Java_com_example_jni_TestJNI_destory
  (JNIEnv * env, jobject obj){
if(pCAdd!=NULL){
delete pCAdd;
pCAdd=NULL;
}
}


到此我們的C/C++部分就全部實現了。

5 創建mk文件

JNI實現了之後就要把C/C++代碼編譯成動態鏈接庫.so文件,這樣Java程序才能調用JNI的接口。要編譯so文件,需要寫Android.mk和Application.mk兩個文件。我們先來寫Android.mk。

先在工程目錄的jni下創建一個Android.mk文件:

\

然後打開文件在裡面輸入如下內容:

LOCAL_PATH := $(call my-dir)
 
include $(CLEAR_VARS) 
 
LOCAL_MODULE    := TestJNI
LOCAL_SRC_FILES := com_example_jni_TestJNI.cpp
LOCAL_SRC_FILES += Add.cpp
 
include $(BUILD_SHARED_LIBRARY)


其中LOCAL_PATH是C/C++代碼所在目錄,也就是我們的jni目錄。

LOCAL_MODULE是要編譯的庫的名稱。編譯器會自動在前面加上lib,在後面加上.so。

LOCAL_SRC_FILES是要編譯的C/C++文件。

現在我們在工程的根目錄下創建一個Application.mk文件,並輸入如下內容:

APP_PROJECT_PATH := ${call my-dir}
APP_MODULES := TestJNI 

6 編譯動態鏈接庫

寫完了mk文件就可以開始編譯C/C++代碼了。

默認在Windows7下配置好了NDK開發環境,打開cygwin,進入到工程目錄。

\

在終端裡進入工程的根目錄,輸入命令“$NDK/ndk-build”命令即可編譯

\

編譯成功後會在工程目錄的libs/armeabi目錄下生成一個libTestJNI.so文件。

\

7 在Java中調用JNI

現在我們的Android應用可以調用JNI計算加法的代碼,如下:

static {
System.load("TestJNI");
}
TextView tvX = null;
TextView tvY = null;
TextView tvSum = null; 
Button   btnAdd = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvX = (TextView)findViewById(R.id.et_x);
tvY = (TextView)findViewById(R.id.et_y);
tvSum = (TextView)findViewById(R.id.et_sum);
btnAdd = (Button)findViewById(R.id.btn_add);
btnAdd.setOnClickListener(new OnClickListener(){
 
@Override
public void onClick(View v) { 
int x = Integer.valueOf( tvX.getText().toString());
int y = Integer.valueOf( tvY.getText().toString());
int sum = 0;
TestJNI jni = new TestJNI();
boolean flag = jni.init();
if(flag){
sum = jni.add(x, y);
}
btnAdd.setText(String.valueOf(sum));
}
});
}

程序運行結果:

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved