Amostra: hello-jni

Esta amostra orienta você pelo hello-jni, um app C/C++ mínimo compilado com o NDK. Essa amostra está no diretório hello-jni do repositório ndk-samples, dentro de android-mk branch.

Android.mk

As duas linhas a seguir fornecem o nome do arquivo de origem nativo, junto ao nome da biblioteca compartilhada a ser criada. O nome completo da biblioteca é libhello-jni.so, após o sistema de compilação acrescentar o prefixo lib e a extensão .so.

    LOCAL_SRC_FILES := hello-jni.c
    LOCAL_MODULE    := hello-jni
    

Para saber mais sobre o que o arquivo Android.mk faz e como usá-lo, consulte Android.mk.

Application.mk

Esta linha informa ao sistema de compilação a CPU e a arquitetura para compilação. Neste exemplo, todas as arquiteturas compatíveis são criadas pelo sistema de compilação.

    APP_ABI := all
    

Para saber mais sobre o arquivo Application.mk e como usá-lo, consulte Application.mk.

Implementação em Java

O arquivo helloJNI.java está localizado em hellojni/src/com/example/hellojni/. Ele chama uma função para recuperar uma string do código nativo e a exibe na tela.

O código-fonte tem três linhas interessantes para o usuário do NDK. Elas são apresentadas aqui na ordem em que são usadas, e não na ordem das linhas.

Esta chamada de função carrega o arquivo .so na inicialização do app.

Kotlin

    System.loadLibrary("hello-jni")
    

Java

    System.loadLibrary("hello-jni");
    

A palavra-chave native nessa declaração de método informa à máquina virtual que a função está na biblioteca compartilhada (ou seja, implementada no código nativo).

Kotlin

    external fun stringFromJNI(): String
    

Java

    public native String stringFromJNI();
    

O framework do Android chama a função carregada e declarada nas etapas anteriores, exibindo a string na tela.

Kotlin

    tv.text = stringFromJNI()
    

Java

    tv.setText( stringFromJNI() );
    

Implementação em C

O arquivo hello-jni.c está localizado em hello-jni/jni/. Ele contém uma função que retorna uma string solicitada pelo lado em Java. A declaração da função é a seguinte:

    JNIEXPORT jstring JNICALL
    Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                      jobject thiz )
    

Essa declaração corresponde à função nativa declarada no código-fonte em Java. O tipo de retorno, jstring, é um tipo de dado definido na Especificação de interface nativa em Java (link em inglês). Ele não é uma string, mas um ponteiro para uma string em Java.

Depois de jstring, temos o nome da função, que é baseado no nome da função Java e no caminho do arquivo que a contém. Siga as regras de construção a seguir:

  • Inclua Java_ no início.
  • Descreva o caminho do arquivo relativo ao diretório de origem de nível superior.
  • Use sublinhados no lugar de barras.
  • Omita a extensão de arquivo .java.
  • Após o último sublinhado, adicione o nome da função.

Com base nessas regras, este exemplo usa o nome da função Java_com_example_hellojni_HelloJni_stringFromJNI. Esse nome se refere a uma função Java chamada stringFromJNI(), localizada em hellojni/src/com/example/hellojni/HelloJni.java.

JNIEnv* é o ponteiro para a VM, e jobject é um ponteiro para o objeto implícito this passado pelo código Java.

A linha a seguir chama a API da VM (*env) e transmite a ela um valor de retorno: ou seja, a string solicitada pela função no código Java.

    return (*env)->NewStringUTF(env, "Hello from JNI !
    Compiled with ABI " ABI ".");