Acesse o contexto do Android no aplicativo ndk

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

Existe alguma maneira em que eu posso passar / obter um objeto de contexto android no meu appliation ndk. Eu quero usar SharedPreferences no meu aplicativo ndk via interface jni. Para obter uma instância do objeto getSharedPreferences() , preciso chamar getSharedPreferences() no objeto Context . Mas eu não tenho acesso ao objeto de contexto.

OU

Como posso ler e gravar um arquivo xml do NDK?

Quaisquer ponteiros serão apreciados.

3 Comments
ognian 12/15/2010
Como ler e gravar arquivos xml: xmlsoft.org
Sebastian Roth 12/15/2010
Apesar de não ter experiência com o NDK, não acho que você possa acessar o contexto. O desenvolvimento do NDK é apenas para tarefas críticas, de alto desempenho e de baixo nível de tempo. Eu sugiro que você encontre os dados de configuração mais críticos que você precisa e escreva-os em JSON ou XML e analise-os a partir do seu código NDK.
Mr.Cool 05/22/2013
@cppdev agora eu também enfrento esse mesmo problema, se você implementou isso, você pode compartilhar

2 Answers


Lucas S. 12/22/2010.

Não há nada de especial que você tenha que fazer, é como o mecanismo JNI comum. Você precisa obter um ponteiro para o objeto de contexto, recuperar o ID do método que deseja chamar e invocá-lo com os argumentos desejados.

Claro que em palavras parece super simples, mas no código fica muito confuso, já que todas as verificações e chamadas do JNI são feitas.

Então, na minha opinião eu não tentarei implementar a coisa toda do código nativo / JNI, ao invés disso eu implementarei um método auxiliar em Java que faz todas as coisas e apenas recebe os dados necessários para ler / escrever a preferência.

Isso simplificará muito o seu código nativo e facilitará a manutenção.

por exemplo:

//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 que eu acabei de escrever o código da memória, então não espere que funcione fora da caixa.

2 comments
Igor Ganapolsky 04/12/2016
O que é variável env ? É um contexto a ser passado no Android?
1 aasu 09/08/2016
@IgorGanapolsky Não precisa ser passado explicitamente como um argumento na chamada de função JNI porque a JVM a transmite internamente. Veja en.wikipedia.org/wiki/Java_Native_Interface#How_the_JNI_work‌ s

dev 02/16/2016.

Parece que as coisas mudaram recentemente e a solução acima e algumas outras postadas em outras postagens de SO não funcionaram para mim. Depois de algumas tentativas, consegui fazer o seguinte trabalho de solução. Meu objetivo era passar o objeto de contexto para o JNI e obter um caminho de armazenamento absoluto.

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
Eu pensei que os argumentos iriam na última posição na lista de parâmetros para GetMethodID acordo com journals.ecs.soton.ac.uk/java/tutorial/native1.1/implementin‌g /… . No entanto, você está passando o contextClass como o primeiro parâmetro?

Related questions

Hot questions

Language

Popular Tags