Webkit JNI study notes

来源:互联网 发布:昆明到大理 汽车 知乎 编辑:程序博客网 时间:2024/05/01 12:29

JNI entrance

1.WebCoreJniOnLoad.cpp,

EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){    JSC::Bindings::setJavaVM(vm);   .....    const RegistrationMethod* method = gWebCoreRegMethods;    const RegistrationMethod* end = method + sizeof(gWebCoreRegMethods)           /sizeof(RegistrationMethod);    while (method != end) {        if (method->func(env) < 0) {            LOGE("%s registration failed!", method->name);            return result;        }        method++;    }    return JNI_VERSION_1_4;}

register the JNI functions for every class

static RegistrationMethod gWebCoreRegMethods[] = {    { "JavaBridge", android::registerJavaBridge },    { "JniUtil", android::registerJniUtil },    { "WebFrame", android::registerWebFrame },    { "WebCoreResourceLoader", android::registerResourceLoader },    { "WebViewCore", android::registerWebViewCore },    ........};

so registerJavaBridge registerJniUtil.... will be called.


2. class's JNI  register methods

take registerWebViewCore for example

int registerWebViewCore(JNIEnv* env){    jclass widget = env->FindClass("android/webkit/WebViewCore");    LOG_ASSERT(widget,            "Unable to find class android/webkit/WebViewCore");    gWebViewCoreFields.m_nativeClass = env->GetFieldID(widget, "mNativeClass",            "I");    .........    return jniRegisterNativeMethods(env, "android/webkit/WebViewCore",            gJavaWebViewCoreMethods, NELEM(gJavaWebViewCoreMethods));}
register every method for the class

3. JNINativeMethod structure

static JNINativeMethod gJavaWebViewCoreMethods[] = {  { "nativeClearContent", "()V", (void*) ClearContent },  ...}
typedef struct {    const char* name;    const char* signature;    void*       fnPtr;} JNINativeMethod;
function name(the name for java to call), signature, and function pointer.

4. native method parameters

take "ClearContent" for example

static void ClearContent(JNIEnv *env, jobject obj)

it has two parameters, one is JNIEvn, the other is it's java object in the vm.

some may have more

static void SetSelection(JNIEnv *env, jobject obj, jint start, jint end)

each function has at least two parameter which are "JNIEnv" and "jobject"

the first is the JNI pointer, the second is the java class who owns the method.

other parameters depends on the implementation of the function.


JAVA's class and method in CPP

1. find class from java in cpp code

    jclass widget = env->FindClass("android/webkit/WebViewCore");

    jclass FindClass(const char* name)

2. find field from a class

     gWebViewCoreFields.m_nativeClass = env->GetFieldID(widget, "mNativeClass","I");

struct WebViewCoreFields {    jfieldID    m_nativeClass;    jfieldID    m_viewportWidth;    .......    jfieldID    m_highUsageDeltaMb;} gWebViewCoreFields;

   jfieldID GetFieldID(jclass clazz, const char* name, const char* sig);
 

here is use a opaque structure 

struct _jfieldID;                       /* opaque structure */typedef struct _jfieldID* jfieldID;     /* field IDs */

so it just return a jfieldID pointer.  (as my understanding it should be a pointer)

struct _jfieldID is an opaque structure, we can only use it's pointer, because we don't know it size.

It can be used when ourselves know what the return type is, andconvert the point to the type we want.

3. setIntField and getIntField

    void SetIntField(jobject obj, jfieldID fieldID, jint value)    { functions->SetIntField(this, obj, fieldID, value); }

    jint GetIntField(jobject obj, jfieldID fieldID)    { return functions->GetIntField(this, obj, fieldID); }

fieldID is a pointer in Java Class

a. setIntField means we assign value to the pointer.

    env->SetIntField(javaWebViewCore, gWebViewCoreFields.m_nativeClass, (jint)this);

so the value of the gWebViewCoreFields.m_nativeClass will be the value of pointer "this", that's "WebViewCore"

b. getIntField means we get the value of the pointer .

#define GET_NATIVE_VIEW(env, obj) ((WebViewCore*)env->GetIntField(obj,        gWebViewCoreFields.m_nativeClass))
so we could get the "WebViewCore" pointer back in some other place.

4. is this necessary to use the global variant?

I think it do that so we don't have to call findClass GetXXField in every function.

(maybe findClass and GetXXField the two will be enough for us wherever we want to use it)

5.GetMethodID

    jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
get a method from a class.

struct _jmethodID;                      /* opaque structure */typedef struct _jmethodID* jmethodID;   /* method IDs */
also opaque structure.

jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
get method "hasNext" of class "iteratorClass"

6. call a method in java

env->CallBooleanMethod(iter, hasNext)
we got the method, and we know what type it is, call the corresponding function.

    jboolean    (*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
ps:

iteratorClass is the class namefor the class, jobject is theobject instance of the class that we are using.



macro defined in jni.h

1.

#define CALL_TYPE_METHOD(_jtype, _jname) _jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...)#define CALL_TYPE_METHODA(_jtype, _jname) #define CALL_TYPE_METHODA(_jtype, _jname)(it's a method a defination of a current jname and method)define call_type_method for a specific jtype and jname.

2.

#define CALL_TYPE(_jtype, _jname)\    CALL_TYPE_METHOD(_jtype, _jname)\    CALL_TYPE_METHODV(_jtype, _jname)\    CALL_TYPE_METHODA(_jtype, _jname)define three functions of a current type and name.

3.
    CALL_TYPE(jobject, Object)    CALL_TYPE(jboolean, Boolean)    CALL_TYPE(jbyte, Byte)    CALL_TYPE(jchar, Char)    CALL_TYPE(jshort, Short)    CALL_TYPE(jint, Int)    CALL_TYPE(jlong, Long)    CALL_TYPE(jfloat, Float)    CALL_TYPE(jdouble, Double)

define the type of all type in Java.
4.
void CallVoidMethod(jobject obj, jmethodID methodID, ...)void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)

5.
#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname) #define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)....void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,jmethodID methodID, jvalue* args)

same as above

6.

getFieldIdsetIntFieldgetIntField


原创粉丝点击