今年下半年, 给上海海思的哥们做过一次android JNI培训,当然培训感兴趣的人不多(都是做芯片的), 讲得很简单,现把培训胶片贴出来:
JNI介绍:
System.loadLibrary(*.so);
System.loadLibrary("simplejni");
}
加载(注册):
ØAndroid_Runtime 中加载
参考:
android_server_BluetoothEventLoop.cpp
AndroidRuntime.cpp
参考:
SampleJNI例子中native.cpp
Android_Runtime中加载:
int register_android_server_BluetoothEventLoop(JNIEnv *env) {
return AndroidRuntime::registerNativeMethods(env,
"android/server/BluetoothEventLoop", sMethods, NELEM(sMethods));
}
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void *)classInitNative},
{"initializeNativeDataNative", "()V", (void *)initializeNativeDataNative},
{"cleanupNativeDataNative", "()V", (void *)cleanupNativeDataNative},
{"startEventLoopNative", "()V", (void *)startEventLoopNative},
{"stopEventLoopNative", "()V", (void *)stopEventLoopNative},
{"isEventLoopRunningNative", "()Z", (void *)isEventLoopRunningNative}
}
JNI_OnLoad:
参考: sampleJNI
java调用C/C++:
参考:development/samples/samplejni
public class SimpleJNI extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
int sum = Native.add(2, 3);
tv.setText("2 + 3 = " + Integer.toString(sum));
setContentView(tv);
}
}
class Native {
static {
// The runtime will add "lib" on the front and ".o" on the end of
// the name supplied to loadLibrary.
System.loadLibrary("simplejni");
}
static native int add(int a, int b);
}
C/C++调用java:
Java_AndroidJniDemo_executeMethod(JNIEnv *env, jobject obj, jclass clazz)
{
// clazz = env->FindClass(className);
jmethodID mid = (*env)->GetMethodID(env, clazz, "show", "()V");
if (mid == NULL) {
return; //如果方法ID没有找到
}
(*env)->CallVoidMethod(env, obj, mid); //执行show方法
}
其它:
void (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
jobject (*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
field_mChannel = get_field(env, clazz, "mChannel", "I");
env->SetIntField(object, field_mChannel, (jint)nat);
其它:
void (*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
…
jobject (*GetObjectField)(JNIEnv*, jobject, jfieldID);
jboolean (*GetBooleanField)(JNIEnv*, jobject, jfieldID);
jboolean (*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
void (*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
…
JNI数据类型:
[ 表示一维数组,[[ 二维数组……
L 表示是对象类型
java.lang.String;(一定要有分号) 对象的标准类名
[I 表示 int [];[L/java/lang/objects;表示Objects[],另外,引用类型(除基本类型的数组外)的标示最后都有个";“
如:
method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
"(Ljava/lang/String;Ljava/lang/String;I)V");
JNI 中的异常:
参考:Jni.h
JNI异常的用法:
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
env->ThrowNew(env->FindClass("java/lang/Exception"),
"xxx异常");
jthrowable mException = env->ExceptionOccurred();
if (mException != NULL) {
env->Throw(mException);
}