您的位置:首页 > 其它

Webkit JNI study notes

2012-01-01 23:46 281 查看
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 the
object 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.

getFieldId
setIntField
getIntField
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: