文章目录
上几篇文章我们介绍了java调用c++代码的一些demo案例,这篇文章我将记录c++调用java代码的一些内容,下面我们把关键步骤演示说明一下!
一、关键步骤演示说明
1、首先我先写一个普通的java方法,如下:
/**
* 用于演示在c++里面调用这个方法
* 写一个java方法
* 这个不是本地native方法,所以有方法体
*/
public void callByCpp(){
//运行程序,如果c++调用了此方法,就会执行此语句
Log.v(TAG, "call by cpp,******************************");
}
2、然后看c++代码是怎么调用 callByCpp 此方法的,如下:
//add code to call Jni callBCpp();
//1、获得对象,此时obj对象就是Jni对象,所以不需要再去获取了
//2、获取类,Jni.callByCpp(); 那么首先要获取Jni类
//java中有一种很重要的概念叫包,即 包名+类名 才能获取到
//com.luminal.ndktest + Jni类 对应 com/luminal/ndktest/Jni
jclass jniclass = env->FindClass("com/luminal/ndktest/Jni");
//3、获取方法(函数)
//参数1:对象名。 参数2:方法名
//参数3:方法签名。"()V" 括号表示callByCpp方法没有参数,V表示callByCpp方法没有返回值,返回值为void
jmethodID methodID = env->GetMethodID(jniclass, "callByCpp", "()V");
//4、调用函数(方法) java中调用方法是这样的:obj.func()
//这里调用java方法,使用方法 CallVoidMethod
//注:env代表java虚拟机。 参数1:对象 参数2:方法
env->CallVoidMethod(obj,methodID);
二、具体代码
1、Jni类
package com.luminal.ndktest;
import android.util.Log;
/**
* 用来封装Jni的native接口的
*/
public class Jni {
private static String TAG ="Jni@@@";
//因为有很多地方要调用到,所以写成单例
private static Jni obj = new Jni();
public static Jni instance() {
return obj;
}
//加载动态库
static {
//动态库的名字,参见"CMakeLists.txt"文件
System.loadLibrary("native-lib");
}
public native String getStringFromJni();
/**
* 用于演示在c++里面调用这个方法
* 写一个java方法
* 这个不是本地native方法,所以有方法体
*/
public void callByCpp(){
//运行程序,如果c++调用了此方法,就会执行此语句
Log.v(TAG, "call by cpp,******************************");
}
}
2、c++代码 native-lib.cpp
#include <jni.h>
#include <string>
extern "C" jstring Java_com_luminal_ndktest_Jni_getStringFromJni(JNIEnv* env, jobject obj){
//add code to call Jni callBCpp();
//1、获得对象,此时obj对象就是Jni对象,所以不需要再去获取了
//2、获取类,Jni.callByCpp(); 那么首先要获取Jni类
//java中有一种很重要的概念叫包,即 包名+类名 才能获取到
//com.luminal.ndktest + Jni类 对应 com/luminal/ndktest/Jni
jclass jniclass = env->FindClass("com/luminal/ndktest/Jni");
//3、获取方法(函数)
//参数1:对象名。 参数2:方法名
//参数3:方法签名。"()V" 括号表示callByCpp方法没有参数,V表示callByCpp方法没有返回值,返回值为void
jmethodID methodID = env->GetMethodID(jniclass, "callByCpp", "()V");
//4、调用函数(方法) java中调用方法是这样的:obj.func()
//这里调用java方法,使用方法 CallVoidMethod
//注:env代表java虚拟机。 参数1:对象 参数2:方法
env->CallVoidMethod(obj,methodID);
//还有很多类似的,有返回类型的方法、静态的方法,如:
//env->CallIntMethod();
//env->CallFloatMethod();
//env->CallStaticIntMethod();
return env->NewStringUTF("Test xxx");
}
3、MainActivity调用演示
package com.luminal.ndktest;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private static String TAG ="MainActivity@@@";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = Jni.instance().getStringFromJni();
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(str);
Log.v(TAG,str);
}
}
4、小结、最终效果
//我们有了java和c++的代码互调后,Android应用程序的开发就完全可以用c++来写一些底层的逻辑和
//全局存储的一些数据都使用c++来实现。那么你在跨平台的时候,你就可以把这些c++的代码,完全移植到ios
//也就是Android 和 ios只是做一些界面效果,核心的东西还是用c++来写,这样的开发效率才是最高的!