Access android context in ndk application

cppdev 12/15/2010. 2 answers, 7.899 views
android android android-ndk android-ndk

Is there any way in which I can pass/get an object of android context in my ndk appliation. I want to use SharedPreferences in my ndk application via jni interface. To get an instance of SharedPreferences object, I need to call getSharedPreferences() on Context object. But I do not have access to the context object.

OR

How can I read and write an xml file from NDK ?

Any pointers will be appreciated.

3 Comments
ognian 12/15/2010
How to read and write xml file: xmlsoft.org
Sebastian Roth 12/15/2010
While having no experience with the NDK, I don't think you can access the context. NDK development is for time-critical, high performance and low-level things only. I suggest you find the most critical configuration data you need and write it out in either JSON or XML and parse it from your NDK code.
Mr.Cool 05/22/2013
@cppdev now i also face this same problem ,if you have implemented this , can you share

2 Answers


Lucas S. 12/22/2010.

There is nothing special you have to do, it is just like regular JNI mechanism. You need to get a pointer to the context object, then retrieve the method ID you want to call and then invoke it with the args you want.

Of course in words it sounds super straightforward, but in code it gets really messy since the all the checks and JNI calls.

So in my opinion i will not try to implement the whole thing from native/JNI code, instead i will implement a helper method in Java that makes all the stuff and just receives the needed data to read/write the preference.

That will simplify a lot your native code and it will make it easier to maintain.

eg:

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

Note that i just wrote the code from memory so expect not to work out of the box.

2 comments
Igor Ganapolsky 04/12/2016
What is env variable? Is is a Context to be passed in Android?
1 aasu 09/08/2016
@IgorGanapolsky It needn't be explicitly passed as an argument in the JNI function call because the JVM internally passes it. See en.wikipedia.org/wiki/Java_Native_Interface#How_the_JNI_work‌​s

dev 02/16/2016.

Looks like things have changes recently and the solution above and few others posted on other SO posts didn't work for me. After few tries I was able to make following solution work. My goal was to pass Context Object to JNI and get absolute storage path.

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;
      }
}
1 comments
Igor Ganapolsky 04/12/2016
I thought arguments go in the last position in parameters list for GetMethodID according to journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementin‌​g/…. However, you are passing contextClass as the first parameter?

Related questions

Hot questions

Language

Popular Tags