android jni 详细介绍

来源:互联网 发布:淘宝号可以转让吗 编辑:程序博客网 时间:2024/06/09 05:53

        今年下半年, 给上海海思的哥们做过一次android JNI培训,当然培训感兴趣的人不多(都是做芯片的), 讲得很简单,现把培训胶片贴出来:

JNI介绍:

ØJava Native Interface (JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI 是本地编程接口,它使得在 Java 虚拟机 (VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++ 和汇编语言)编写的应用程序和库进行交互操作。

Ø应用层的Java类是在虚拟机(VM: Vitual Machine)上执行的,而C件不是在VM上执行,那么Java程式又如何要求VM去载入(Load)所指定的C组件呢? 可使用下述指令:

System.loadLibrary(*.so);

Ø static {

       System.loadLibrary("simplejni");

    }

加载(注册):

ØAndroid_Runtime 中加载

   参考: 

  android_server_BluetoothEventLoop.cpp

  AndroidRuntime.cpp

ØJNI_OnLoad

    参考:

  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 方法

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, ...);

Ø调用java 字段

  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 中的异常:

Øjboolean ExceptionCheck()
Øjthrowable ExceptionOccurred()
Øvoid ExceptionDescribe()
Øvoid ExceptionClear()
Øjint Throw(jthrowable obj)
Ø jint ThrowNew(jclass clazz, const char* message)

参考: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);

}

 

 

 

原创粉丝点击