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

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

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio 中使用 Java 调用 C++ 实例需要进行以下步骤: 1. 编写 C++ 代码,并将其打包成可供 Java 调用的库文件(.so 文件)。 2. 在 Java 中使用 JNIJava Native Interface)调用 C++ 库。 下面是一个简单的示例: 1. 编写 C++ 代码并将其打包成库文件 在 C++ 中编写代码,将其打包成可供 Java 调用的库文件。以下是一个简单的示例,在 C++ 中实现一个函数,计算两个整数的和,并将其打包成库文件: ```c++ // sum.cpp #include <jni.h> extern "C" JNIEXPORT jint JNICALL Java_com_example_sum_MainActivity_sum(JNIEnv *env, jclass clazz, jint a, jint b) { return a + b; } ``` 编译 C++ 代码,并将其打包成可供 Java 调用的库文件。可以使用 Android NDK 工具链来编译 C++ 代码,并生成库文件。以下是一个简单的示例: ```shell $ cd /path/to/project $ ndk-build ``` 编译完成后,将会在项目的 libs 目录下生成库文件(.so 文件)。在本例中,生成的库文件名为 libsum.so。 2. 在 Java 中使用 JNI 调用 C++ 库 在 Java 中使用 JNI 调用 C++ 库,需要进行以下步骤: a. 加载库文件: 在 Java 中使用 System.loadLibrary() 方法加载库文件。以下是一个简单的示例: ```java static { System.loadLibrary("sum"); } ``` 在本例中,将会加载名为 libsum.so 的库文件。 b. 声明本地方法: 在 Java 中声明本地方法,即 JNI 调用 C++ 库中的函数。以下是一个简单的示例: ```java public static native int sum(int a, int b); ``` c. 实现本地方法: 在 Java 中实现本地方法,即调用 JNI 调用 C++ 库中的函数。以下是一个简单的示例: ```java public static int sum(int a, int b) { return sum(a, b); } private static native int sum(int a, int b); ``` 在本例中,调用 sum() 方法时,会调用本地方法 sum(),并最终调用 C++ 库中的 sum() 函数。 至此,完成了在 Android Studio 中使用 Java 调用 C++ 实例的过程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值