2015-09-14 34 views
0

我想在Android中使用本地代碼從C++文件中調用java方法。我知道,我們可以通過JNI實現這一點,但在這種情況下,我需要發起Java調用,這不符合我的要求。Android中的C++和Java之間的通信

我需要在C++中調用main()函數用Java編寫的方法。

那麼有沒有其他的方法來實現這個沒有JNI?

如果我能用JNI來實現這個事情,請告訴我怎麼做?

在此先感謝。

謝謝你, Maulik

回答

0

你檢查這一點:
https://developer.android.com/ndk/samples/sample_hellojni.html 我基本上從那裏學到。或者:
1. https://github.com/sureshjoshi/android-ndk-swig-example
2. https://github.com/googlesamples/android-ndk
一個簡單的搜索會讓你在所有這些地方。
Calling a java method from c++ in Android
編輯 現在,一旦你用這個做,它在下一次從C/C++調用效果很好。該 片段,它應該幫助你的是:

#include <string.h> 
#include <jni.h> 
//other imports 

jstring get_package_MainActivity_getJniString(JNIEnv* env, jobject obj){ 

    jstring jstr = (*env)->NewStringUTF(env, "MainActivity class"); 
    jclass clazz = (*env)->FindClass(env, "com/org/android/ui/activities/MainActivity"); 
    jmethodID mCurrentActivityId = (*env)->GetMethodID(env, clazz, "getCurrentActivityName", "(Ljava/lang/String;)Ljava/lang/String;"); 
    jobject result = (*env)->CallObjectMethod(env, obj, mCurrentActivityId, jstr); 

    const char* str = (*env)->GetStringUTFChars(env,(jstring) result, NULL); // should be released but what a heck, it's a tutorial :) 
    printf("%s\n", str); 

    return (*env)->NewStringUTF(env, str); 
} 
+0

我檢查了他們,但事情是他們使用JNI調用C到JAVA,反之亦然,在JNI中,我們需要首先在Java中啓動調用,然後我們可以從C調用到JAVA。 我想要的是從C調用JAVA而不用JAVA啓動它。 – MMJ

0

我覺得你的目的,你需要使用JNI,以通過JVM參數(的JNIEnv * ENV,jobject OBJ),然後並將其作爲全球/你的c/C++代碼中的靜態變量。將其視爲您應用的初始階段。

一旦您的c/C++端代碼準備好調用java方法,您可以使用全局/靜態變量來啓動對java方法的調用,如代碼片段andrei所提供的。一些符合:

JNIEnv* cSideEnv; // global, set using JNI call in java 
jobject cSideObj; // global, set using JNI call in java 

void get_package_MainActivity_setCsideJvm(JNIEnv* env, jobject obj){ 
    cSideEnv = env; 
    cSideObj = obj; 
} 

void myCsideCallToJava() { 
    jstring jstr = (*cSideEnv)->NewStringUTF(cSideEnv , "MainActivity class"); 
    jclass clazz = (*cSideEnv)->FindClass(env, 
     "com/org/android/ui/activities/MainActivity"); 
    jmethodID mCurrentActivityId = (*cSideEnv)->GetMethodID(cSideEnv , clazz, 
     "getCurrentActivityName", "(Ljava/lang/String;)Ljava/lang/String;"); 
    jobject result = (*cSideEnv)->CallObjectMethod(cSideEnv , cSideObj, 
     mCurrentActivityId, jstr); 
} 

void main(.....) { 
    // init - precondition for calling java is running the java side setCsideJvm 
    // which sets cSideEnv and cSideObj 
    ..... 
    // ready to call java 
    myCsideCallToJava(); 
} 

由於您使用JNI,我相信你的應用程序將您的應用程序的C/C++的一部分之前運行的Java的一部分,所以這個解決方案應該幫助你。

如果您正在使用2個進程(一個java,一個c/C++),那麼這是一個完全不同的問題,可以通過IPC解決方案解決。

+0

在我的情況下,整個系統是由C/C++項目驅動的。 *所以首先將運行C++部分,它將調用Java類中的方法,然後使用AIDL調用android中的服務設計。* 需要使用哪種IPC解決方案來實現上述方案發展? – MMJ

+0

其實我是Android和NDK開發的新手。這就是我需要問這麼多問題的原因:) – MMJ

+0

我對android開發沒有經驗,只有JNI和IPC解決方案。根據你的意見,似乎你有一個java方法的特定需求,對於純粹的c/C++項目。IPC解決方案將要求您同時進行2個進程 - c/C++主進程和專用java進程(用於單個方法調用)。這似乎是對你的問題矯枉過正。既可以實現Java方法的c/C++版本,也可以使用c/C++ JNI內核將項目切換到java。這是我能做的最好的。 –