最近在看了很多JNI資料,用了各種方法,但個人卻喜歡這種方式,廢話不多說。
一、在android源碼package目錄下創建一個文件夾TestJni,並創建兩個目錄,分別爲test_jni.cpp和Android.mk
二、編寫test_jni.cpp:
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <assert.h>
//#include <cutils/log.h>
#include <string.h>
#include <jni.h>
#include "android_runtime/AndroidRuntime.h"
static const char *kClassName = "com/example/test_jni/testjni"; //需要註冊的類,注意我的是testjni.java
jint openportNative(JNIEnv *env,jobject obj,int state)
{
//printf("+++++++OpenPort++++++++\n");
state = 111;
return state;
}
jint closeportNative(JNIEnv *env,jobject obj,int state)
{
//printf("+++++++ClosePort++++++++\n");
state = 222;
return state;
}
static JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{"openport", "(I)I", (void*)openportNative}, //綁定 ,openport爲java應用層的接口,對應JNI openportNative接口;
{"closeport", "(I)I", (void*)closeportNative}
};
jint JNI_OnLoad(JavaVM *vm, void *reserved) //這個很重要,詳細說明不解散;
{
JNIEnv *env = NULL;
jclass cls;
jint result = -1;
if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
cls = env->FindClass((const char*)kClassName);
if (cls == NULL) {
return -1;
}
if (env->RegisterNatives( cls, gMethods, sizeof(gMethods)/sizeof(gMethods[0])) < 0) {
return -1;
}
result=JNI_VERSION_1_4;
return result;
}
三、編寫Android.mk文件:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PRELINK_MODULE := false
LOCAL_SRC_FILES:= test_jni.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE)
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime
LOCAL_MODULE := libtest_jni
LOCAL_MODULE_TAGS := eng
include $(BUILD_SHARED_LIBRARY)
四、執行source build/envsetup.sh---->lunch xxx -----> make test_jni -j4
編譯完成後.so文件將直接保存到out/target/product/xxxxx/system/lib/目錄下,將他拷貝到eclipse的libs目錄下即可,接下來我們調用下接口;
五、MainActivity.java 代碼很簡單,新建兩個按鈕,然後訪問庫文件的接口,並接受返回值,數值確認是正確的。
package com.example.test_jni;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.example.testjni.R;
import com.example.test_jni.testjni;
public class MainActivity extends Activity {
private Button btn1,btn2;
int red;
static {
System.loadLibrary("test_jni"); //靜態加載庫
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final testjni j = new testjni(); //創建一個對象,這個對象看下面的代碼,裏面有包含native方法
btn1 = (Button)findViewById(R.id.bt1);
btn2 = (Button)findViewById(R.id.bt2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
red = j.openport(111); //執行native openport方法
System.out.println("red========="+red);
}
});
btn2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
red =j.closeport(222); //同上
System.out.println("red========="+red);
}
});
}
}
六、testjni.java類
package com.example.test_jni;
public class testjni {
static {
System.loadLibrary("test_jni");
}
public native int openport(int a); //本地方法
public native int closeport(int b);
}
七、在eclipse編譯成APK文件,安裝APK。