2010-12-15 4 views
6

Есть ли способ передать/получить объект андроидного контекста в моем приложении ndk. Я хочу использовать SharedPreferences в моем приложении ndk через интерфейс jni. Чтобы получить экземпляр объекта SharedPreferences, мне нужно позвонить getSharedPreferences() на объект Context. Но у меня нет доступа к объекту контекста.Доступ к контексту android в приложении ndk

ИЛИ

Как я могу читать и писать файл XML с NDK?

Любые указатели будут оценены.

+0

Как читать и писать файл XML: http://xmlsoft.org/ – ognian 2010-12-15 12:35:34

+0

Пока не имея опыта работы с NDK, я не думаю, что вы можете получить доступ к контексту. Разработка NDK предназначена только для критически важных, высокопроизводительных и низкоуровневых вещей. Я предлагаю вам найти наиболее важные данные конфигурации, которые вам нужны, и записать их в JSON или XML и проанализировать их из вашего кода NDK. – 2010-12-15 14:00:17

+0

@cppdev теперь я тоже сталкиваюсь с этой же проблемой, если вы это сделали, можете ли вы делиться – 2013-05-22 11:54:27

ответ

6

Нет ничего особенного, что вам нужно сделать, это как обычный механизм JNI. Вам нужно получить указатель на объект контекста, затем получить идентификатор метода, который вы хотите вызвать, а затем вызвать его с помощью требуемых аргументов.

Конечно, на словах это звучит очень просто, но в коде он становится очень грязным, поскольку все проверки и вызовы JNI.

Так что, на мой взгляд, я не буду пытаться реализовать все это из собственного/JNI-кода, вместо этого я реализую вспомогательный метод в Java, который делает все это, и просто получает необходимые данные для чтения/записи предпочтений.

Это упростит ваш собственный код и упростит его поддержку.

например:

//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); 
     } 
    } 
} 

Обратите внимание, что я просто написал код из памяти, поэтому ожидать, чтобы не работать из коробки.

1

Похоже, что в последнее время произошли изменения, и решение выше и несколько других, опубликованных на других сообщениях СО, не работало для меня. После нескольких попыток я смог сделать следующее решение. Моя цель состояла в том, чтобы передать объект контекста в JNI и получить абсолютный путь хранения.

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; 
     } 
}