工程的目录结构如下:
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String[] argv=new String[]{"mylib","Gao","GaoMatrix"};
Natives.libMain(argv);
}
}
/**
* @author GaoMatrix E-mail:gcquan08@gmail.com
* @version Time:2011-8-20
*/
public class Natives {
static{
System.loadLibrary("mylib");
}
public static native int libMain(String[] argv);
private static void onMessage(String text,int level){
// System.out.println("Message:"+text+" Level:"+level);
Log.d("JNI", "Message:"+text+" Level:"+level);
}
}
Android.mk:
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:=mylib
LOCAL_SRC_FILES:=mylib.c
LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
include/Natives.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Natives */
#ifndef _Included_Natives
#define _Included_Natives
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Natives
* Method: libMain
* Signature: ([Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_com_gao_Natives_libMain
(JNIEnv *, jclass, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif
mylib.c:
#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include "include/Natives.h"
#include <android/log.h>
#define LOG_TAG "JNI"
#define LOGD(a) __android_log_write(ANDROID_LOG_DEBUG,LOG_TAG,a)
#define CB_CLASS "com/gao/Natives"
/**
* onMessage callback
*/
#define CB_CLASS_MSG_CB "onMessage"
#define CB_CLASS_MSG_SIG "(Ljava/lang/String;I)V"
//lib main sub
int lib_main(int argc,char **argv);
//Used to get the len of a java Array
const int getArrayLen(JNIEnv* env,jobjectArray jarray);
//print str message back to java
void jni_printf(char* format,...);
//Global env ref(for callback)
static JavaVM* g_VM;
//Global Reference to the native java calss com.gao.Natives.java
static jclass jNativesCls;
JNIEXPORT jint JNICALL Java_com_gao_Natives_libMain
(JNIEnv *env, jclass cls, jobjectArray jarray)
{
//obtain a global ref to the caller class
(*env)->GetJavaVM(env,&g_VM);
//Extract char **args from java array
jsize len=getArrayLen(env,jarray);
char* args[(int)len];
int i;
jstring jrow;
for(i=0;i<len;i++)
{
//Get C string from Java String[i]
jrow=(jstring)(*env)->GetObjectArrayElement(env,jarray,i);
const char* row=(*env)->GetStringUTFChars(env,jrow,0);
args[i]=malloc(strlen(row)+1);
strcpy(args[i],row);
//print args
jni_printf("Main argv[%d]=%s",i,args[i]);
//LOGD("From C "+*args[i]);
LOGD("From C ");
//free java string jrow
(*env)->ReleaseStringUTFChars(env,jrow,row);
}
//Load the com.gao.Natives class
jNativesCls=(*env)->FindClass(env,CB_CLASS);
if(jNativesCls==0)
{
jni_printf("Unable to find class:%s",CB_CLASS);
return -1;
}
//Invoke the lib main sub.This will loop forener
//Program agrs com from Java
lib_main(len,args);
return 0;
}
/**
*Send a string back to Java
*/
jmethodID mSendStr;
static void jni_send_str(const char* text,int level)
{
JNIEnv* env;
if(!g_VM)
{
printf("I_JNI_NOVM:%s\n",text);
return;
}
(*g_VM)->AttachCurrentThread(g_VM,(void **)&env,NULL);
//Load jni.Natives if missing
if(!jNativesCls)
{
jNativesCls=(*env)->FindClass(env,CB_CLASS);
if(jNativesCls==0)
{
printf("Unable to find class:%s",CB_CLASS);
return;
}
}
//Call com.gao.Natives.onMessage(String,int)
if(!mSendStr)
{
//Get a ref to the static method:com.gao.Natives.onMessage
mSendStr=(*env)->GetStaticMethodID(env,jNativesCls
,CB_CLASS_MSG_CB
,CB_CLASS_MSG_SIG);
}
if(mSendStr)
{
(*env)->CallStaticVoidMethod(env,jNativesCls
,mSendStr
,(*env)->NewStringUTF(env,text)
,(jint)(level));
}else
{
printf("Unable to find method: %s, signature: %s\n"
, CB_CLASS_MSG_CB, CB_CLASS_MSG_SIG );
}
}
/**
*Get java array length
*/
const int getArrayLen(JNIEnv* env,jobjectArray jarray)
{
return (*env)->GetArrayLength(env,jarray);
}
/**
* Printf into the java layer
* does a varargs printf into a temp buffer
* and calls jni_sebd_str
*/
void jni_printf(char* format,...)
{
va_list argptr;
static char string[1024];
va_start(argptr,format);
vsprintf(string,format,argptr);
va_end(argptr);
jni_send_str(string,0);
}
/**
*Library main sub
*/
int lib_main(int argc,char** argv)
{
int i;
jni_printf("Entering LIB MAIN");
for(i=0;i<argc;i++)
{
jni_printf("Lib Main argv[%d]=%s",i,argv[i]);
}
return 0;
}
运行结果:
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[0]=mylib Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[1]=Gao Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Main argv[2]=GaoMatrix Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): From C
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Entering LIB MAIN Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[0]=mylib Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[1]=Gao Level:0
08-20 21:50:50.350: DEBUG/JNI(7574): Message:Lib Main argv[2]=GaoMatrix Level:0