Desenvolvimento - Mobile (MS)

Android NDK: Desmistificando o acesso a códigos nativos em C

Acredito que quase todo usuário da plataforma Android provavelmente já questionou como é possível algumas aplicações gráficas apresentarem tamanha performance...

por Alessandro de Oliveira Faria



Acredito que quase todo usuário da plataforma Android provavelmente já questionou como é possível algumas aplicações gráficas apresentarem tamanha performance, mesmo com modelos de equipamentos que apresentam o mais modesto hardware e/ou versão do Android? O NDK (Native Development Kit) é a resposta para todas estas dúvidas e muitas outras.


Introdução e instalação

O Android NDK proporciona o recurso de acesso direto à GPU utilizando OpenGL ( viva \o/ ), logo torna-se possível a utilização de recursos como vertex, shaders e fragment shaders. Recursos fundamentais para os efeitos especiais em aplicações gráficas, sem contar no facilitador em termos de trabalho para os desenvolvedores.

O Android NDK é o segundo kit de desenvolvimento disponível para programadores interessados no sistema operacional Android. O kit convencional é o Android SDK (Software Development Kit), onde o programador desenvolve na linguagem Java (já mencionada aqui no portal Linha de Código http://www.linhadecodigo.com.br/artigo/2811/Instalando-o-Android-SDK-na-plataforma-Linux.aspx ).

Com o NDK é possível escrever bibliotecas em C ou C++, sem mistério e com muita rapidez, e integrá-las em aplicativos Java sem a necessidade de magia-negra, o que deriva em ganho de produtividade na elaboração do aplicativo. Em contrapartida, pode-se perder a portabilidade. Pois smartphones Android usam uma ampla variedade de processadores, e bibliotecas nativas. Com isto talvez seja necessário a recompilação dos executáveis, ao contrário do aplicativos 100% escrito em Java.

Download e instalação

O NDK deve ser obtido na página oficial do Android, ou seja:

· http://developer.android.com/sdk/ndk/index.html


Quando este documento foi elaborado, para efetuar o download, foi preciso apenas o comando a seguir. Entretanto claro, este link mudará conforme os próximo release e/ou versão.

$ wget http://dl.google.com/android/ndk/android-ndk-r5b-linux-x86.tar.bz2

Após o download, descompacte o pacote conforme o exemplo abaixo:

$ tar -jxvf android-ndk-r5b-linux-x86.tar.bz2

Pronto! Neste etapa o Android NDK foi instalado com sucesso (difícil não)!


Mão na massa! Criando o Hello Word com JNI

A técnica de abstração de funções C e/ou classes em C++ é denominada JNI, ou Java Native Interface, é um padrão de programação que permite que a máquina virtual da linguagem Java acesse bibliotecas construídas com o código nativo de um sistema. Junto ao recurso do NDK para compilação cruzada, céu é o limite para as pessoas que não conhecem os seus limites.

Chega de blá-blá-blá e começaremos agora a colocar a mão na massa, selecionando a opção File->New->Project conforme a figura abaixo.

Na nova janela de diálogo, selecione a opção Android Project.

Logo a seguir, informe o nome do projeto no EditBox project name, selecione o item "Create new project in workspace", habilite o item "Use default location" para criar no workspace padrão e por fim a versão do SDK. Na figura a seguir veremos um exemplo ilustrativo.

Informe o nome da aplicação, o nome do pacote e também o nome da Acticity.

Edite o arquivo main.xml localizado na pasta layout, conforme o exemplo abaixo:

Altere a classe HelloNDK conforme o exemplo abaixo, onde a função nativa sayHello() retorna uma string java que posteriormente será exibida na aplicação. Reparem que a chamada da biblioteca nativa hellondk é efetuada com System.loadLibrary.

package com.cabelo.hellondk;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class HelloNDK extends Activity {

   TextView txtHello;

   @Override

   public void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);

      setContentView(R.layout.main);

      txtHello = (TextView) findViewById(R.id.txtHello);

      String hello = sayHello();

      txtHello.setText(hello);

      }

   public native String sayHello();

   static {

      System.loadLibrary("hellondk");

      }

}


Salve o projeto e no modo console (\o/ viva!), entre na pasta do projeto com o comando cd.

$ cd ~/workspace/olaNDK/

Utilizaremos o javah, um gerador de arquivos header para integração a código nativo em C. Este programa possibilita que programas escritos em Java façam chamadas de procedimentos escritos em C. A sua sintaxe é composta do arquivo de saída precedido da classe java como no exemplo abaixo:

$ javah -o hellondk.h -classpath bin com.cabelo.hellondk.HelloNDK


Agora crie a pasta jni e mova o arquivo .h criado anteriormente para a pasta recém-criada.

$ mkdir jni
$ mv hellondk.h jni/


Entre na pasta jni e cria o arquivo Application.mk informando a arquitetura de processador a utilizar.

$ cd jni/
$ echo "APP_ABI := armeabi armeabi-v7a" > Application.mk


A seguir, crie também o arquivo Android.mk com o conteúdo do exemplo abaixo.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#I Like to build my shared libs using C++
LOCAL_DEFAULT_CPP_EXTENSION := cpp

LOCAL_MODULE := hellondk
LOCAL_SRC_FILES := hellondk.cpp

include $(BUILD_SHARED_LIBRARY)

Agora falta criar apenas o arquivo hellondk.cpp, cujo conteúdo é na integra a abstração C em Java, ou seja, como prova de conceito, retornaremos uma string java oriunda da junção sayHello. No exemplo a seguir, o conteúdo do arquivo hellondk.cpp.

#include <hellondk.h>

JNIEXPORT jstring JNICALL Java_com_cabelo_hellondk_HelloNDK_sayHello(JNIEnv *env, jobject obj){
    return env->NewStringUTF("Viva o
Linux
com NDK!");
}

Para compilar, basta utilizar o script ndk-build no NDK:

$ /dados/neti/programas64/android-ndk-r5/ndk-build

StaticLibrary  : libstdc++.a

SharedLibrary  : libhellondk.so

Install        : libhellondk.so => libs/armeabi/libhellondk.so

StaticLibrary  : libstdc++.a

SharedLibrary  : libhellondk.so

Install        : libhellondk.so => libs/armeabi-v7a/libhellondk.so

Pronto, agora basta voltar no Eclipse, abrir o aplicativo Java e executá-lo. Se tudo estiver funcionando corretamente, teremos um resultado conforme a imagem a seguir...

Espero que este documento ajude a desmistificar o uso do NDK na plataforma Android, principalmente para os iniciantes. Como sempre menciono... Colaborar atrai amigos, competir atrai inimigos...

Sobre o autor: http://www.netitec.com.br/alessandro

Alessandro de Oliveira Faria

Alessandro de Oliveira Faria - Sócio-proprietário da empresa NETi TECNOLOGIA fundada em Junho de 1996 (http://www.netitec.com.br), empresa especializada em desenvolvimento de software e soluções biométricas, Consultor Biométrico na tecnologia de reconhecimento facial, atuando na área de tecnologia desde 1986 assim propiciando ao mercado soluções em software nas mais diversas linguagens e plataforma, levando o Linux a sério desde 1998 com desenvolvimento de soluções open-source, membro colaborador da comunidade Viva O Linux, mantenedor da biblioteca open-source de vídeo captura entre outros projetos.