static jint RegisterNatives(JNIEnv
*
env,
jclass java_class,
const JNINativeMethod
*
methods,
jint method_count) {
if
(UNLIKELY(method_count <
0
)) {
JavaVmExtFromEnv(env)
-
>JniAbortF(
"RegisterNatives"
,
"negative method count: %d"
,
method_count);
return
JNI_ERR;
/
/
Not reached
except
in
unit tests.
}
CHECK_NON_NULL_ARGUMENT_FN_NAME(
"RegisterNatives"
, java_class, JNI_ERR);
ClassLinker
*
class_linker
=
Runtime::Current()
-
>GetClassLinker();
ScopedObjectAccess soa(env);
StackHandleScope<
1
> hs(soa.Self());
Handle<mirror::Class> c
=
hs.NewHandle(soa.Decode<mirror::Class>(java_class));
if
(UNLIKELY(method_count
=
=
0
)) {
LOG(WARNING) <<
"JNI RegisterNativeMethods: attempt to register 0 native methods for "
<< c
-
>PrettyDescriptor();
return
JNI_OK;
}
CHECK_NON_NULL_ARGUMENT_FN_NAME(
"RegisterNatives"
, methods, JNI_ERR);
for
(jint i
=
0
; i < method_count;
+
+
i) {
const char
*
name
=
methods[i].name;
const char
*
sig
=
methods[i].signature;
const void
*
fnPtr
=
methods[i].fnPtr;
if
(UNLIKELY(name
=
=
nullptr)) {
ReportInvalidJNINativeMethod(soa, c.Get(),
"method name"
, i);
return
JNI_ERR;
}
else
if
(UNLIKELY(sig
=
=
nullptr)) {
ReportInvalidJNINativeMethod(soa, c.Get(),
"method signature"
, i);
return
JNI_ERR;
}
else
if
(UNLIKELY(fnPtr
=
=
nullptr)) {
ReportInvalidJNINativeMethod(soa, c.Get(),
"native function"
, i);
return
JNI_ERR;
}
bool
is_fast
=
false;
if
(
*
sig
=
=
'!'
) {
is_fast
=
true;
+
+
sig;
}
/
/
上面是一些参数验证
ArtMethod
*
m
=
nullptr;
bool
warn_on_going_to_parent
=
down_cast<JNIEnvExt
*
>(env)
-
>GetVm()
-
>IsCheckJniEnabled();
for
(ObjPtr<mirror::Class> current_class
=
c.Get();
current_class !
=
nullptr;
current_class
=
current_class
-
>GetSuperClass()) {
/
/
查询方法对应的 ArtMethod 对象
m
=
FindMethod<true>(current_class, name, sig);
if
(m !
=
nullptr) {
break
;
}
/
/
Search again comparing to
all
methods, to find non
-
native methods that match.
m
=
FindMethod<false>(current_class, name, sig);
if
(m !
=
nullptr) {
break
;
}
if
(warn_on_going_to_parent) {
LOG(WARNING) <<
"CheckJNI: method to register \""
<< name <<
"\" not in the given class. "
<<
"This is slow, consider changing your RegisterNatives calls."
;
warn_on_going_to_parent
=
false;
}
}
if
(m
=
=
nullptr) {
c
-
>DumpClass(LOG_STREAM(ERROR), mirror::Class::kDumpClassFullDetail);
LOG(ERROR)
<<
"Failed to register native method "
<< c
-
>PrettyDescriptor() <<
"."
<< name << sig <<
" in "
<< c
-
>GetDexCache()
-
>GetLocation()
-
>ToModifiedUtf8();
ThrowNoSuchMethodError(soa, c.Get(), name, sig,
"static or non-static"
);
return
JNI_ERR;
}
else
if
(!m
-
>IsNative()) {
/
/
非 native 方法是不能注册的
LOG(ERROR)
<<
"Failed to register non-native method "
<< c
-
>PrettyDescriptor() <<
"."
<< name << sig
<<
" as native"
;
ThrowNoSuchMethodError(soa, c.Get(), name, sig,
"native"
);
return
JNI_ERR;
}
VLOG(jni) <<
"[Registering JNI native method "
<< m
-
>PrettyMethod() <<
"]"
;
if
(UNLIKELY(is_fast)) {
LOG(WARNING) <<
"!bang JNI is deprecated. Switch to @FastNative for "
<< m
-
>PrettyMethod();
is_fast
=
false;
/
/
TODO: make this a hard register error
in
the future.
}
/
/
最终调用 class_linker
-
>RegisterNative 来实际进行注册
const void
*
final_function_ptr
=
class_linker
-
>RegisterNative(soa.Self(), m, fnPtr);
UNUSED(final_function_ptr);
}
return
JNI_OK;
}