androidC++和Java通过JNI机制相互调用

xiaoxiao2021-02-28  69

上篇文章添加了一个自定义的系统服务,并且可以获取使用该服务。这篇文章在上篇文章的基础上,

利用JNI机制实现该系统服务对应的C++文件,本篇文章基于android 6.0。

目标:

1,java通过JNI机制可以调用C++中的方法

2,C++调用java中的方法

1, MyService创建方法

frameworks/base/services/core/java/com/android/server/路径下的MyService.java如下,

package com.android.server; import android.os.IMyService; import android.util.Log; class MyService extends IMyService.Stub { private String myName ; private String myCName ; public MyService(){ } @Override public void setName(String mname){ myName = mname; } @Override public String getName(){ getNameNative(); return myCName; } public void getCName(String str){ myCName = myName + " C_Java " + str; Log.d("android ", "myCName: " + myCName); } public native void (); }

新添加一个getNameNative方法,调用对应的C++的getNameNative方法。

新添加一个getCName方法,供C++的进行调用。

2,添加对应的C++文件

1,在frameworks/base/services/core/jni路径下添加com_android_server_MyService.cpp文件,主要内容如下,

namespace android { static void getNameNative(JNIEnv *env, jobject object) { //调用 LOGI("native getNameNative"); jclass clazz = env->FindClass("com/android/server/MyService"); jmethodID methodID = env->GetMethodID(clazz, "getCName", "(Ljava/lang/String;)V"); env->CallVoidMethod(object,methodID,env->NewStringUTF(" Java_C is successed")); } static JNINativeMethod sMethods[] = { {"getNameNative", "()V", (void*)getNameNative}, }; int register_android_server_MyService(JNIEnv* env) //注册 { LOGI("register_android_server_MyService"); return jniRegisterNativeMethods(env, "com/android/server/MyService", sMethods, NELEM(sMethods)); } }

2,在frameworks/base/services/core/jni路径下Android.mk文件LOCAL_SRC_FILES中添加如下内容,

LOCAL_SRC_FILES += \ ••• $(LOCAL_REL_DIR)/com_android_server_MyService.cpp \ •••

3,frameworks/base/services/core/jni路径下的onload.cpp文件中,

在namespace android 中最后添加

int register_android_server_MyService(JNIEnv* env);

在extern "C" jintJNI_OnLoad(JavaVM* vm, void* /* reserved */)中添加

register_android_server_MyService(env);

当然这些文件的路径根据实际情况有所不同。

 

3,代码分析

在apk中,

mMyServiceManager = (MyServiceManager)getSystemService("MyService"); mMyServiceManager.setName("my_stystem_service"); Log.d("android " , "getName" + mMyServiceManager.getName());

最后输出: 

my_stystem_service C_Java Java_C is successed

调用的逻辑如下,

1,首先调用系统服务MyService的getName方法。

2,系统服务MyService通过JNI机制调用com_android_server_MyService.cpp的getNameNative方法。

3,在com_android_server_MyService.cpp的getNameNative方法中调用系统服务MyService的getCName方法为变量myCName赋值。

4,最后返回系统服务MyService的变量myCName。

转载请注明原文地址: https://www.6miu.com/read-64370.html

最新回复(0)