2010-12-15 9 views
6

Gibt es eine Möglichkeit, in der ich ein Objekt von Android-Kontext in meiner ndk-Anwendung übergeben/erhalten kann. Ich möchte SharedPreferences in meiner ndk-Anwendung über jni Schnittstelle verwenden. Um eine Instanz von SharedPreferences Objekt zu bekommen, muss ich getSharedPreferences() auf Context Objekt aufrufen. Aber ich habe keinen Zugriff auf das Kontextobjekt.Zugriff auf Android-Kontext in ndk-Anwendung

ODER

Wie kann ich eine XML-Datei von NDK lesen und schreiben?

Alle Hinweise werden geschätzt.

+0

Wie Lesen und Schreiben xml-Datei schreiben: http://xmlsoft.org/ – ognian

+0

Während keine Erfahrung mit dem NDK hat, glaube ich nicht, dass Sie den Kontext zugreifen können. NDK-Entwicklung ist nur für zeitkritische, hohe Leistung und Low-Level-Dinge. Ich schlage vor, dass Sie die wichtigsten Konfigurationsdaten finden, die Sie benötigen, und schreiben Sie sie entweder in JSON oder XML aus und parsen Sie sie aus Ihrem NDK-Code. –

+0

@cppdev Jetzt habe ich auch das gleiche Problem, wenn Sie dies implementiert haben, können Sie teilen –

Antwort

6

Es gibt nichts besonderes zu tun, es ist wie normale JNI-Mechanismus. Sie müssen einen Zeiger auf das Kontextobjekt abrufen, dann die Methoden-ID abrufen, die Sie aufrufen möchten, und sie dann mit den gewünschten Argumenten aufrufen.

Natürlich in Worten klingt es super einfach, aber im Code wird es wirklich chaotisch, da alle Schecks und JNI Anrufe.

Also meiner Meinung nach werde ich nicht versuchen, das Ganze aus nativem/JNI-Code zu implementieren, stattdessen werde ich eine Hilfsmethode in Java implementieren, die all das Zeug macht und nur die benötigten Daten zum Lesen/Schreiben der Präferenz empfängt.

Das wird Ihren nativen Code viel vereinfachen und die Pflege erleichtern.

zB:

//Somewhere inside a function in your native code 
void Java_com_example_native_MainActivity_nativeFunction(JNIEnv* env, jobject thiz) 
{ 
    jclass cls = (*env)->FindClass(env,"PreferenceHelper"); 
    if (cls == 0) printf("Sorry, I can't find the class"); 

    jmethodID set_preference_method_id; 

    if(cls != NULL) 
    { 
     set_preference_method_id = (*env)->GetStaticMethodID(env, cls, "setPreference", "(Ljava/lang/String;Ljava/lang/StringV"); 

     if(set_preference_method_id != NULL) 
     { 
      jstring preference_name = (*env)->NewStringUTF(env, "some_preference_name"); 
      jstring value = (*env)->NewStringUTF(env, "value_for_preference"); 

      (*env)->CallStaticVoidMethod(env, cls, get_main_id, preference_name, value); 
     } 
    } 
} 

Bitte beachte, dass ich nur den Code aus dem Speicher geschrieben, so erwarte nicht, aus dem Kasten heraus zu arbeiten.

+0

Was ist 'env' Variable? Ist ein Context in Android zu übergeben? –

+1

@IgorGanapolsky Es muss nicht explizit als Argument im JNI-Funktionsaufruf übergeben werden, da die JVM es intern übergibt. Siehe https://en.wikipedia.org/wiki/Java_Native_Interface#How_the_JNI_works – aasu

1

Sieht so aus, als hätten die Dinge in letzter Zeit Änderungen erfahren, und die obige Lösung und einige andere, die auf anderen SO-Posts gepostet wurden, funktionierten nicht für mich. Nach einigen Versuchen konnte ich folgende Lösungsarbeit leisten. Mein Ziel war es, Context Object an JNI zu übergeben und den absoluten Speicherpfad zu erhalten.

void Java_com_path_to_my_class_jniInit(JNIEnv* env, jobject thiz, jobject contextObject) { 

    try { 
     //Get Context Class descriptor 
     jclass contextClass = env->FindClass("android/content/Context"); 
     //Get methodId from Context class 
     jmethodID getFilesDirMethodId = env->GetMethodID(contextClass,"getFilesDir","()Ljava/io/File;"); 

     //Call method on Context object which is passed in 
     jobject fileObject = env->CallObjectMethod(contextObject,getFilesDirMethodId); 

     //Get File class descriptor 
     jclass fileClass = env->FindClass("java/io/File"); 
     //Get handle to the method that is to be called 
     jmethodID absolutePathMethodId = env->GetMethodID(fileClass,"getAbsolutePath","()Ljava/lang/String;"); 
     //Call the method using fileObject 
     jstring stringObject = (jstring)env->CallObjectMethod(fileObject,absolutePathMethodId); 
     } 
     catch(exception& ex){ 
      JNIExceptionHelper::throwException(env, ex.what()); 
      return; 
     } 
} 
+0

Ich dachte Argumente gehen an der letzten Stelle in der Parameterliste für 'GetMethodID' nach http://journals.ecs.soton.ac.uk/java/ Tutorial/native1.1/Implementierung/Methode.html. Übergeben Sie jedoch 'contextClass' als ersten Parameter? –