An open API service indexing awesome lists of open source software.

https://github.com/crissalvarezh/addcodigocenandroid

Proyecto de ejemplo para integrar código nativo en C en Android.
https://github.com/crissalvarezh/addcodigocenandroid

android c cpp java jni jni-android ndk

Last synced: 3 months ago
JSON representation

Proyecto de ejemplo para integrar código nativo en C en Android.

Awesome Lists containing this project

README

          

# Descripción
Este proyecto se creó a modo de ejemplo para integrar codigo C/C++ en un proyecto de Android utilizando JNI y NDK.
A continuación están los pasos a seguir para lograr este integración.

# Demostración
La aplicación Android suma dos numeros enteros, cada vez que se hace un cambio en alguno de los numero se realiza de nuevo la suma, esta
suma está hecha en el lenguaje C.

![Demo](https://github.com/CrissAlvarezH/ImagenesRepos/blob/master/imgs/AddCodigoCEnAndroid/demo.gif)

# Guía

Esta guía está separada en varias partes, la integración de codigo C en el cual
muestro como escribir codigo C en un proyecto de Android, la creación de las librerías compartidas `.so`, el consumo de dichas librerias, la importación de la librería en un proyecto distinto al donde fue construida y por ultimo usaremos codigo C++ en vez de C y
agregaremos logs para verlos en el LogCat de Android Studio.

## Integración con codigo C

Clase con metodo navite

Empezamos creando una clase en Java que contendrá los metodos que se escribirán en C. Como puedes notar utilizamos la palabra reservada
`native` para declarar el metodo, tambien puedes notar que no tiene cuerpo, esto es porque el cuerpo se lo definiremos en C.

Compilar clase nativa

Compilamos la clase que acabamos de crear utilizando `javac`, esto nos dará como resultado un `.class`

Crear cabecera

Ahora creamos el fichero de cabecera JNI para dicha clase, esto lo hacemos con el comando
`javah -c java .`, posteriormente
creamos un directorio llamado `jni` y movemos nuestro `.h`, recién creado, dentro.

Cabecera

Al abrir el archivo podemos ver que contiene la función que hemos declarado en `ClaseNativa.java`, pero su nombre tiene la siguiente estructura
`Java___`.

Crear c

Ahora debemos crear el codigo C asociado a esa cabecera, para esto copiamos el archivo y lo pegamos en la misma carpeta pero le cambiamos la
extención de `.h` a `.c` y le hacemos los siguientes cambios

Codigo c jni

En el archivo `.c` que creamos en el anterior paso vamos a implementar el codigo C de la función, le definimos los parametros y le creamos el cuerpo a la función. Aquí lo que vemos es una simple suma hecha en el lenguaje C.

## Crear librearías compartidas `.so`

Ahora que ya tenemos el codigo hecho lo que resta es crear las librerías para su posterior consumo en el codigo Java.

Android mk

Creamos un archivo llamado `Android.mk` en la carpeta `jni` el cual tendrá las ordenes necesarias para la creación de las librerías.
Una vez hecho esto podemos proceder a crear las librerías.

Comando ndk-build

El comando `ndk-build` realiza la tarea de construir las librerías para cada una de las arquitecturas, si lo deseamos podemos especificarle
que arquitecturas queremos pasandole el parametro `APP_ABI = x86` por ejemplo.
Sin embargo, otra forma de hacerlo es crear un archivo `Application.mk` (opcional) en la carpeta `jni` donde especifiquemos esto.

Application mk

Aquí especificamos que queremos todas las arquitecturas.

Librerías compiladas

La ejecución del anterior comando nos da como resultado las librerías para todas las arquitecturas en una carpeta llamada `libs`.

## Consumo de las librerías

Ahora procedemos con la parte mas sencilla, utilizar las librerías para ejecutar el codigo C en nuestro proyecto Android. Para esto debemos
renombrar la carpeta `libs` a `jniLibs` y despues agregar las siguientes lineas de codigo a nuestra clase `ClaseNativa.java`

Librerías compiladas

El nombre debe ser el de la librería sin el prefijo `lib`y sin la extención `.so`

Y con todo esto ya podremos hacer uso de nuestra suma en C llamando a la funcion `ClaseNativa.sumar()`.

## Importación de las librerías en otro proyecto

Hasta este punto ya puede ejecutar codigo nativo en C en tu proyecto de android donde construiste la librería compartida. Pero te darás
cuenta que si tomas estas librerías `.so` y las incluyes en otro proyecto no te van a funcionar. La razón es que la función `sumar` de la librería está siendo exportada para una determinada clase de un paquete en específico, este paquete es el del proyecto en donde se construyó. Por lo tanto, para que funcione en otro proyecto debes renombrar las funciones y los archivos exportados por JNI, el nombre que debes colocarle es el del paquete de el del nuevo proyecto donde quieres correr la librería, veamos el proceso.

Vamos a suponer que el proyecto donde queremos usar la librería tiene el paquete `com.paquete.deprueba.importacion.libreria.libreria`, haremos lo siguiente.

Librerías compiladas

Vamos a cambiar las partes resaltadas (en la imagen ya están cambiadas) por el nuevo paquete cambiando los puntos por guiones bajos.
En la imagen superior estamos ubicados en la cabecera.

Librerías compiladas

Hacemos el mismo procedimiento en el archivo donde importamos la cabecera e implementamos el codigo C de la función.

Librerías compiladas

La ultima parte donde debemos cambiarlo es en el archivo Android.mk para que construya las librerías partiendo de los archivos renombrados.

Y listo, lo que sigue es volver a construir las librerías utilizando el comando `ndk-build` tal como lo hicimos anteriormente.

## Usar codigo C++ e imprimir logs

Ahora lo que queremos es usar codigo C++ en vez de C, para eso simplemente renombramos nuestro archivo `.c` a `.cpp`, sin embargo, si
utilizamos importaciones como `#include ` vamos a notar el siguiente error.

Librerías compiladas

Para solucionarlo agregamos la siguiente linea al archivo `Application.mk`

Librerías compiladas

Una vez agregada esa linea, volvemos a construir la librería y no se presenta ningun problema.
Ahora procederemos a implementar codigo C++ y a agregar Logs para poder verlos en nuestra consola.
Para agregar logs incluimos la cabecera: `android/log.h` en nuestro codigo. Posteriormente agregamos la siguiente linea en `Android.mk`

Librerías compiladas

Con esto agregado podemos utilizar la siguiente funcion para imprimir logs.

Librerías compiladas

Si todo lo anterior está OK, el resultado será el siguiente

Librerías compiladas

En la imagen de arriba podemos ver en el LogCat los logs que definimos en el codigo de C++