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

来源:互联网 发布:服装erp软件 编辑:程序博客网 时间:2024/06/09 14:49

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

利用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。

0 0