Ă fĂĄcil criar e fazer o aplicativo funcionar com uma pequena quantidade de cĂłdigo nativo. Se vocĂȘ deseja usar uma biblioteca nativa, na qual existem muitos arquivos, fica mais difĂcil. A dificuldade Ă© que as bibliotecas nativas sĂŁo distribuĂdas na forma de cĂłdigo-fonte que precisa ser compilado para a arquitetura de processador desejada. Usando o codec de ĂĄudio Opus como exemplo, mostrarei como fazĂȘ-lo.
 
Opus , Android, Opus, . - .so .a, , C/C++ . . Opus , NDK .so .a, Android-.
, C/C++, . Opus (.a).
C , . #include <fileWithHeaders.h>. C , (.a), #include <fileWithHeaders.h> . (.so), . , , , .
.so . , Opus , Android, . libjniopus.so , libopus.a, libopus.so.
NDK c 19 « ». , . , , , . , .
Opus
: (git clone), . Opus Autoconf â , . Autoconf toolchain , ENV-. Autoconf, , Unix . Windows, , , .
4 .a : armeabi-v7a, arm64-v8a, x86, x86-64.
ENV-. NDK, HOST_TAG TOOLCHAIN. Linux, ENV- , export:
export NDK=/home/vital/Android/Sdk/ndk/20.1.5948944
export HOST_TAG=linux-x86_64
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
ENV- , , . , . ENV- , .bashrc, (~). .bashrc. , , . ENV-, :
export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
export CC=$TOOLCHAIN/bin/aarch64-linux-android21-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android21-clang++
export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as
export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang
export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi21-clang++
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export AR=$TOOLCHAIN/bin/i686-linux-android-ar
export AS=$TOOLCHAIN/bin/i686-linux-android-as
export CC=$TOOLCHAIN/bin/i686-linux-android21-clang
export CXX=$TOOLCHAIN/bin/i686-linux-android21-clang++
export LD=$TOOLCHAIN/bin/i686-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/i686-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/i686-linux-android-strip
export AR=$TOOLCHAIN/bin/x86_64-linux-android-ar
export AS=$TOOLCHAIN/bin/x86_64-linux-android-as
export CC=$TOOLCHAIN/bin/x86_64-linux-android21-clang
export CXX=$TOOLCHAIN/bin/x86_64-linux-android21-clang++
export LD=$TOOLCHAIN/bin/x86_64-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/x86_64-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/x86_64-linux-android-strip
arm64-v8a, .bashrc ENV- . , CC CXX 21, Android API level. , , minSdkVersion. 21, , . NDK 16 29 32- ABI (armeabi-v7a x86) 21 29 64- ABI (arm64-v8a x86-64).
, ENV-, toolchain , Opus. Readme Opus , - :
$ ./autogen.sh
$ ./configure
$ make
. , 4 .
NDK r19 « » toolchains. , ENV- ( .bashrc), , . configure host. arm64-v8a :
$ source ~/.bashrc
$ ./autogen.sh
$ ./configure --host aarch64-linux-android
$ make
source ~/.bashrc , «» .
, Opus .libs. , libopus.a.
.bashrc /, ENV- armeabi-v7a, host:
$ source ~/.bashrc
$ ./configure --host armv7a-linux-androideabi
$ make
./autogen.sh , configure, .
make . , - . , , , , ( configure host). , , , , , .
. , Opus. , .
- 4 ENV- . , bash-, . :
#!/bin/bash
export NDK=/home/vital/Android/Sdk/ndk/20.1.5948944
export HOST_TAG=linux-x86_64
export TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
if [[ $# -ne 3 && $# -ne 2 ]] 
then
  echo "You should specify at least minSdkVersion and path to Opus directory"
  echo "Example ./buildOpus.sh 21 <pathToOpusDir> <pathToBuildDir>"
  exit
fi
minSdk=$1
opusPath=$2
if [[ $# -eq 3 ]]
then
  buildPath=$3
else
  buildPath=./opus_android_build
  if [[ -d $buildPath ]]; then
    echo "opus_android_build directory already existed..."
    echo "clearing opus_android_build directory..."
    rm -rfv $buildPath && mkdir $buildPath
  else
    echo "creating opus_android_build directory..."
    mkdir opus_android_build
  fi
fi
echo "Executing autogen.sh"
$opusPath/autogen.sh
if [[ $minSdk -lt 21 ]]
then
  triples=("armv7a-linux-androideabi" "i686-linux-android")
  abis=("armeabi-v7a" "x86")
else
  triples=("aarch64-linux-android" "armv7a-linux-androideabi" "i686-linux-android" "x86_64-linux-android")
  abis=("arm64-v8a" "armeabi-v7a" "x86" "x86-64")  
fi
BIN=$TOOLCHAIN/bin
cd $buildPath 
for i in ${!triples[@]}
do
  triple=${triples[$i]}
  abi=${abis[$i]}
  echo "Building $abi..."
  if [[ $triple == "armv7a-linux-androideabi" ]]
  then
    export AR=$BIN/arm-linux-androideabi-ar
    export AS=$BIN/arm-linux-androideabi-as
    export CC=$BIN/$triple$minSdk-clang
    export CXX=$BIN/$triple$minSdk-clang++
    export LD=$BIN/arm-linux-androideabi-ld
    export RANLIB=$BIN/arm-linux-androideabi-ranlib
    export STRIP=$BIN/arm-linux-androideabi-strip
  else
    export AR=$BIN/$triple-ar
    export AS=$BIN/$triple-as
    export CC=$BIN/$triple$minSdk-clang
    export CXX=$BIN/$triple$minSdk-clang++
    export LD=$BIN/$triple-ld
    export RANLIB=$BIN/$triple-ranlib
    export STRIP=$BIN/$triple-strip
  fi
  mkdir $abi && cd $abi 
  $opusPath/configure --host $triple
  make
  cd ..  
done
echo "Artifacts successfully built for minSdkVersion=$minSdk and ABIs:" 
printf '%s ' "${abis[@]}"
echo ""
echo "Artifacts are located in .libs directory"
, ENV- .bashrc , .
, :
$ sudo chmod +x buildOpus.sh
NDK HOST_TAG, Linux ( linux-x86_64):
- 32-bit Windows: windows
 - 64-bit Windows: windows-x86_64
 - macOS: darwin-x86_64
 
:
$ ./buildOpus.sh 21 <pathToOpusDir> <pathToBuildDir>
minSdkVersion Opus. , . opus_android_build , buildOpus.sh.
. opus_android_build , , ABI, . , .libs, .
, 4 libopus.a , . Android- CmakeLists.txt, .so Opus.
app/src/main/cpp, C- (jniopus.c), external Kotlin. includes. include Opus. (.h). Opus C-. , , .
app/src/main/cpp libopus, 4 , ABI, Opus: armeabi-v7a, arm64-v8a, x86, x86-64. libopus.a, .
CmakeLists.txt, , Opus . «» . :
set(NATIVE_SOURCES_PATH "${PROJECT_SOURCE_DIR}/src/main/cpp")
set(OPUS_HEADERS_PATH "${NATIVE_SOURCES_PATH}/includes")
set(OPUS_LIB_PATH "${NATIVE_SOURCES_PATH}/libopus")
Opus :
add_library(
        libopus
        STATIC
        IMPORTED)
add_library . , , STATIC(.a) SHARED(.so) , IMPORTED, . () :
set_target_properties( 
        libopus PROPERTIES
        IMPORTED_LOCATION "${OPUS_LIB_PATH}/${ANDROID_ABI}/libopus.a")
ANDROID_ABI NDK toolchain , ABI.
-, external Kotlin, :
add_library( 
        jniopus
        
        SHARED
        
        ${NATIVE_SOURCES_PATH}/jniopus.c)
, « » NDK :
find_library( 
        log-lib
        
        
        log)
:
target_link_libraries(
        
        jniopus
        
        libopus ${log-lib})
, , . , Gradle, Run, . , Start call . , , .
, NDK toolchains ABI . , CmakeLists.txt . , Autoconf , pre-19 NDK, . , , .
« Android»: https://vk.com/@forasoft-kak-ispolzovat-nativnye-biblioteki-v-android
: https://gitlab.com/vitaliybelyaev/opus-android
Opus codec: http://opus-codec.org/, https://github.com/xiph/opus
Using the NDK with other build systems: https://developer.android.com/ndk/guides/other_build_systems
Android- CMake: https://developer.android.com/studio/projects/add-native-code#create-cmake-script
ABI Android: https://developer.android.com/ndk/guides/abis