我正在使用带有 C++ 的 android NDK,我面临的问题是我不知道如何创建 c++ 类的对象以访问其在活动中的方法。
知道怎么做吗?谢谢。
首先,Activity
从 MVC 的角度来看,它是一个控制器,当屏幕方向从垂直变为水平时,Activity 会被销毁。首先创建一个能够比活动寿命更长的类,并从那里使用本机资源。
我假设您知道如何创建和调用本机函数,并且知道如何创建 C++ 对象。我也假设你知道什么
#ifdef __cplusplus
extern "C" {
#endif
和
#ifdef __cplusplus
}
#endif
在 .h 文件中执行(它们允许用 C++ 编译的函数(不是成员函数,只是函数)从 C 中可见)。
现在,从 Java 调用 C++ 对象实例方法与从普通 C 调用 C++ 对象实例方法基本相同。
myObject.myMethod(arg1,arg2, ...)
你将不得不做
callMyMethod(myObjHandle, arg1, arg2, ...)
其中 myObjHandle 可能是转换为 int 的 C++ 对象的本机地址。
当然,您将不得不关心删除该 C++ 对象——Java 无法知道必须将某个整数值传递给 C++delete
或delete[]
它。
对您来说一个好消息是相同的线程用于 Java 和本机代码。
要从 Activity 调用 C++ 方法,您需要将该方法声明为“本机”。
//MultiPlayerJNI.java
public static native void onNetworkDataReceived(int index);
//MultiPlayerJNI.h
void Java_com_example_game_MultiPlayerJNI_onNetworkDataReceived(JNIEnv *env, jobject thiz, jint spIndex);
//MultiPlayerJNI.cpp
void Java_com_example_game_MultiPlayerJNI_onNetworkDataReceived(JNIEnv *env, jobject thiz, jint spIndex){
DebugLog("JNI onNetworkDataReceived");
if(MultiplayerJNI::getInstance()->multiGameController != NULL){
MultiPlayerJNI::getInstance()->multiGameController->onNetworkDataReceived(spIndex);
}else if(MultiPlayerJNI::getInstance()->singleGameController != NULL){
MultiPlayerJNI::getInstance()->singleGameController->onNetworkDataReceived(spIndex);
}
}
从 C++ 调用 Java 方法
//MultiPlayerJNI.h
void getTableInfo();
//MultiPlayerJNI.cpp
void MultiPlayerJNI::getTableInfo(){
DebugLog("MultiPlayerJNI::getTableInfo()");
JniMethodInfo t;
if (JniHelper::getStaticMethodInfo(t
, "com/example/game/MultiPlayerJNI"
, "getTableInfo"
, "()V"))
{
t.env->CallStaticVoidMethod(t.classID,t.methodID);
t.env->DeleteLocalRef(t.classID);
}
}
//MultiPlayerJNI.java
public static void getTableInfo(){
}
我建议为 Java 和 CPP 部分创建单例 JNI 类。
我有时在我的 Android 项目中使用 C 或 C++。但是在 C/C++ 源代码中创建 Java 对象。如果您将在 Java 源代码中创建 C++ 类,也许...
(我明白你想要什么,只有我给出一个想法。也许在 C++ 源代码中创建 Java 对象)
这是我的示例;(在本机代码中部署的 Java 对象示例中。)
// JAVA CODE
public class mActivity extends Activity{
public native Object get();
public native void set(Object data);
}
// C CODE
typedef struct data_type
{
jobject data;
struct data_type* next;
}DATA_TYPE;
jobject Java_com_example_nativequeue_TestActivity_get(JNIEnv* env, jobject thiz)
{
if(HEADER != NULL){
jobject result = HEADER->data;
--data_struct_size;
return result;
}
if(HEADER->next != NULL)
HEADER = HEADER->next;
return NULL;
}
void Java_com_example_nativequeue_TestActivity_set(JNIEnv* env, jobject thiz, jobject data)
{
jobject new_data = (*env)->NewGlobalRef(env, data);
if(new_data == NULL){
return;
}
NEW = (DATA_TYPE*)malloc(sizeof(DATA_TYPE));
NEW->data = new_data;
NEW->next = NULL;
if(HEADER == NULL){
HEADER = NEW;
FOOTER = HEADER;
}else{
FOOTER->next = NEW;
FOOTER = NEW;
}
++data_struct_size;
}