NDK env->GetStaticMethodID源碼解析

在NDK中,我們通過env->GetStaticMethodID來查找一個靜態方法,那返回值jmethodID到底是什麼了? 接下來,來看一下GetStaticMethodID內部邏輯。

env->GetStaticMethodID實際會調用jni_internal.cc#GetStaticMethodID
來看 art/runtime/jni_internal.cc
在這裏插入圖片描述
可以看到最終調用了FindMethodID,主要步驟,已通過代碼註釋標記。

static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
                              const char* name, const char* sig, bool is_static)
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  mirror::Class* c = EnsureInitialized(soa.Self(), soa.Decode<mirror::Class*>(jni_class)); //確認是否已經初始化完畢
  if (c == nullptr) {
    return nullptr;
  }
  mirror::ArtMethod* method = nullptr;
  if (is_static) { //是否是靜態函數
    method = c->FindDirectMethod(name, sig);
  } else if (c->IsInterface()) { //是否是接口函數
    method = c->FindInterfaceMethod(name, sig); //--> 實際調用的也是FindVirtualMethod
  } else { //是否是虛函數
    method = c->FindVirtualMethod(name, sig);
    if (method == nullptr) {
      // No virtual method matching the signature.  Search declared
      // private methods and constructors.
      method = c->FindDeclaredDirectMethod(name, sig);
    }
  }
  if (method == nullptr || method->IsStatic() != is_static) {
  	// >>>>>>>> 如果method爲null或不爲static,拋出NoSuchMethodError,這個開發時候經常會遇到
    ThrowNoSuchMethodError(soa, c, name, sig, is_static ? "static" : "non-static");
    return nullptr;
  }
  return soa.EncodeMethod(method); //將ArtMethod進行編碼,返回一個jmethodID
}

可以看到,會判斷是否是靜態函數,如果是靜態函數,就調用FindDirectMethod,否則無論是接口函數還是虛函數,都是調用的FindVirtualMethod。這兩個方法具體內部邏輯我們先略過,從返回值可以知道,這兩個方法都會找到ArtMethod。

再來看art/runtime/scoped_thread_state_change.h#EncodeMethod()

jmethodID EncodeMethod(mirror::ArtMethod* method) const
    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
  Locks::mutator_lock_->AssertSharedHeld(Self());
  DCHECK(IsRunnable());  // Don't work with raw objects in non-runnable states.
  CHECK(!kMovingMethods);
  return reinterpret_cast<jmethodID>(method); //將ArtMethod強轉爲jmethodId,即ArtMethod就是jmethodId
}

這裏將找到的ArtMethod強轉爲jmethodID,即ArtMethod就是jmethodID,並最終返回。

小結

我們可以得出結論: ArtMethod就是jmethodID

ArtMethod位於art/runtime/mirror/art_method.cc,是一個結構體,ArtMethod中保存着方法的 類、訪問權限和執行地址等信息。

其他

源碼爲Android 5.1.0_r3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章