在真机上实践JNI
第一步,在Eclipse中新建一个Android工程,创建HelloWorldActivity
package com.spt3rd; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.view.View.OnClickListener; public class HelloWorldActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mButton = (Button)findViewById(R.id.button1); mButton.setOnClickListener(new OnClickListener(){ public void onClick(View v){ String s = printJNI("hello jni, I'm from Activity"); } }); } static { //加载库文件 System.loadLibrary("HelloWorldActivityJni"); } //声明原生函数 参数为String类型 返回类型为String private native String printJNI(String inputStr); private Button mButton; }
第二步:生成共享库头文件
进入到代码根目录HelloWorld/
进入到bin中,执行:javah com.spt3rd.HelloWorldActivity
生成文件com_spt3rd_HelloWorldActivity.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_spt3rd_HelloWorldActivity */ #ifndef _Included_com_spt3rd_HelloWorldActivity #define _Included_com_spt3rd_HelloWorldActivity #ifdef __cplusplus extern "C" { #endif /* * Class: com_spt3rd_HelloWorldActivity * Method: printJNI * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_spt3rd_HelloWorldActivity_printJNI (JNIEnv *, jobject, jstring); #ifdef __cplusplus } #endif #endif
第三步:实现JNI函数
创建com_spt3rd_HelloWorldActivity.c文件
#include <jni.h> #define LOG_TAG "HelloWorld" #include <utils/Log.h> /* Native interface, it will be call in java code */ JNIEXPORT jstring JNICALL Java_com_spt3rd_HelloWorldActivity_printJNI(JNIEnv *env, jobject obj,jstring inputStr) { LOGI("dufresne Hello World From libhelloworld.so!"); // 从 instring 字符串取得指向字符串 UTF 编码的指针 const char *str = (const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE ); LOGI("dufresne--->%s",(const char *)str); // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。 (*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str ); return (*env)->NewStringUTF(env, "Hello World! I am Native interface"); } /* This function will be call when the library first be load. * You can do some init in the libray. return which version jni it support. */ jint JNI_OnLoad(JavaVM* vm, void* reserved) { void *venv; LOGI("dufresne----->JNI_OnLoad!"); if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) { LOGE("dufresne--->ERROR: GetEnv failed"); return -1; } return JNI_VERSION_1_4; }
第四步:创建jni的Android.mk
在根目录HelloWorld下创建jni文件夹,将com_spt3rd_HelloWorldActivity.h和com_spt3rd_HelloWorldActivity.c都复制到里面。
新建Android.mk
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:=com_spt3rd_HelloWorldActivity.c LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) LOCAL_MODULE := libHelloWorldActivityJni LOCAL_SHARED_LIBRARIES := libutils LOCAL_PRELINK_MODULE := false LOCAL_MODULE_TAGS := optional include $(BUILD_SHARED_LIBRARY)
第五步:创建HelloWorld的Android.mk
# Copyright 2007-2008 The Android Open Source Project LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := HelloWorld include $(BUILD_PACKAGE) # This finds and builds the test apk as well, so a single make does both. include $(call all-makefiles-under,$(LOCAL_PATH))
第六步,将整体移到Android源代码的packages/apps/下面
编译这个APK,会生成
HelloWorld.apk 和 libHelloWorldActivityJni.so
adb install HelloWorld.apk
adb push libHelloWorldActivityJni.so system/lib