加载中 ...
首页 > 常见问题 正文

干货|JNI实现机制

2019-03-24 10:31:08 来源:沈阳软件公司 作者:沈阳软件开发

 

so加载焦点历程:

https://mmbiz.qpic.cn/mmbiz_jpg/yCBu7HSwemKib4cLfWfibGeM6h1c56tOhrmkEkgzPPpNibgxm2jwzzrOInhl8SCU9qd8cia8owXbvkHd3LY05xbuBw/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

class中当地要领加载历程:

https://mmbiz.qpic.cn/mmbiz_jpg/yCBu7HSwemKib4cLfWfibGeM6h1c56tOhrLcXPCKbClGJDWrtJpg44I9W59iaibfMygZtUWCYTNvMG2MvaPwdnrxKw/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

当地要领挪用历程:

https://mmbiz.qpic.cn/mmbiz_jpg/yCBu7HSwemKib4cLfWfibGeM6h1c56tOhrGia123zEicEDHicLNXzIZ3DeibCPl14aia1gE5w4uFhOibtqLP9ptKMaBXYA/640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1

JNIEnv作用及实现

 

JNIEnv是JNI指针接口,通常我们通过它来挪用操作Java工具,它提供了所有的操作java工具的api。

那么JNIEnv又是何时建立,以及怎样来操作Java工具的呢?我们一起来看看它的详细实现~

首先我们来看下线程时怎样被建立的:

java/lang/Thread.java

new Thread().start() -> VMThread.create()

public synchronized void start() {

checkNotStarted();

hasBeenStarted = true;

VMThread.create(this, stackSize);// VMThread建立

}

/dalvik/vm/native/java_lang_VMThread.cpp

Dalvik_java_lang_VMThread_create() -> Thread.dvmCreateInterpThread()

const DalvikNativeMethod dvm_java_lang_VMThread[] = {

{ "create", "(Ljava/lang/Thread;J)V",

Dalvik_java_lang_VMThread_create },//线程建立要领

{ "currentThread", "()Ljava/lang/Thread;",

Dalvik_java_lang_VMThread_currentThread },

//……

};

 

static void Dalvik_java_lang_VMThread_create(const u4* args, JValue* pResult)

{

//……

dvmCreateInterpThread(threadObj, (int) stackSize);//建立线程

RETURN_VOID();

}

 

/dalvik/vm/Thread.cpp

dvmCreateInterpThread() -> interpThreadStart() -> jni.dvmCreateJNIEnv()

bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)

{

//......

Thread* newThread = allocThread(stackSize);

//......

int cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart, newThread);//建立线程

// ......

}

 

/*

* pthread entry function for threads started from interpreted code.

*/

static void* interpThreadStart(void* arg)

{

//......

self->jniEnv = dvmCreateJNIEnv(self);//建立jniEnv

//......

return NULL;

}

 

JNIEnv的建立

/dalvik/vm/jni.cpp

dvmCreateJNIEnv()

JNIEnv* dvmCreateJNIEnv(Thread* self) {

JavaVMExt* vm = (JavaVMExt*) gDvmJni.jniVm;

//……

newEnv->funcTable = &gNativeInterface;//接口函数

//......

return (JNIEnv*) newEnv;

}

 

static const struct JNINativeInterface gNativeInterface沈阳微信小程序

<a href=http://www.hvihi.com target=_blank class=infotextkey>沈阳<a href=http://www.hvihi.com target=_blank class=infotextkey>软件开发</a></a>,<a href=http://www.hvihi.com target=_blank class=infotextkey>沈阳<a href=http://www.hvihi.com target=_blank class=infotextkey>软件公司</a></a>

= {

DefineClass,

FindClass,

//......

CallVoidMethod,

//...

GetFieldID,

GetObjectField,

//...

CallStaticIntMethod,

//......

};

 

//要领详细实现(下面是callVoidMethodA()详细实现)

    CALL_VIRTUAL(_ctype, _jname, _retfail, _retok, _isref)

static _ctype Call##_jname##Method(JNIEnv* env, jobject jobj,

jmethodID methodID, ...)

{

ScopedJniThreadState ts(env);

Object* obj = dvmDecodeIndirectRef(ts.self(), jobj);

const Method* meth;

va_list args;

JValue result;

meth = dvmGetVirtualizedMethod(obj->clazz, (Method*)methodID);

if (meth == NULL) {

return _retfail;

}

va_start(args, methodID);

dvmCallMethodV(ts.self(), meth, obj, true, &result, args);//要领挪用

va_end(args);

if (_isref && !dvmCheckException(ts.self()))

result.l = (Object*)addLocalReference(ts.self(), result.l);

return _retok;

}

CALL_VIRTUAL(jobject, Object, NULL, (jobject) result.l, true);

//......

/dalvik/vm/interp/Stack.cpp

JNIEnv.CallVoidMethodA() -> Stack.dvmCallMethodA()

void dvmCallMethodA(Thread* self, const Method* method, Object* obj,

bool fromJni, JValue* pResult, const jvalue* args)

{

//......

if (dvmIsNativeMethod(method)) {

TRACE_METHOD_ENTER(self, method);

(*method->nativeFunc)((u4*)self->interpSave.curFrame, pResult,

method, self);//执行要领

“沈阳软件公司”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与

我们联系删除或处理,客服QQ:55506560,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同

其观点或证实其内容的真实性。

推荐阅读