NDK編程--鳥瞰

目錄

  • 什么場景下需要NDK
  • 基本概念

什么場景下需要NDK

  • 項目需要調用底層的一些C/C++的一些東西(java無法直接訪問到操作系統]底層(如系統硬件等),需要在su上執行的腳本等情況),或者使用成熟的C/C++開源庫。NDK開發常用于驅動開發、無線熱點共享、數學運算、實時渲染的游戲、音視頻處理、文件壓縮、人臉識別、圖片處理等。
  • 效率角度:將要求高性能的應用邏輯使用C/C++開發,從而提高應用程序的執行效率。但是C/C++代碼雖然是高效的,在java與C/C++相互調用時卻增大了開銷;
  • 安全角度考慮。防止代碼被反編譯,為了安全起見,使用C/C++語言來編寫重要的部分以增大系統的安全性,最后生成so庫(用過第三方庫的應該都不陌生)便于給人提供方便。(任何有效的代碼混淆對于會smail語法反編譯你apk是分分鐘的事,即使你加殼也不能幸免高手的攻擊)
  • 跨平臺,便于移植。用C/C++寫得庫可以方便移植到其他嵌入式平臺。

基本概念

** NDK**:Native Development Kit,是一系列工具的集合。可以把c/c++ ->編譯成一個Linux下可以執行的二進制文件Java代碼里面就可以通過jni調用執行二進制的文件。它提供了一系列的工具,幫助開發者快速開發C/C++的動態庫,并能自動將so和Java一起打包成apk。
JNI:Java Native Interface,標準是java平臺的一部分,JNI是Java語言提供的Java和C/C++相互溝通的機制。
so:shared object,即共享庫,ELF(Executable and Linkable Format,在計算機科學中,是一種用于二進制文件、可執行文件、目標代碼、共享庫和核心轉儲格式文件,是UNIX作為ABI而發布的可執行文件)文件是Linux下的動態鏈接庫,類似于Windows下的dll。生成so文件,主要通過GCC編譯將.c轉成.o,然后通過GCC鏈接將.o轉成.so。庫文件分為動態庫和靜態庫,.a為靜態庫。
ABI:Application Binary Interface,實際就是指應用程序基于哪種指令集來進行編譯,能用到的ABI 也就四種 armeabi,armeabi-v7a ,x86 和mips ,前兩者是比較常見。

  • armeabi,默認選項,將創建以基于 ARM* v5TE 的設備為目標的庫。 具有這種目標的浮點運算使用軟件浮點運算。 使用此 ABI 創建的二進制代碼將可以在所有 ARM* 設備上運行。
  • armeabi-v7a’創建支持基于 ARM* v7 的設備的庫,并將使用硬件 FPU 指令。
  • x86 生成的二進制代碼可支持包含基于硬件的浮點運算的 IA-32 指令集.
  • mips 支持應用二進制接口

APP_ABI 就是為了交叉編譯生成相應芯片可執行的指令集。直觀的看就是如果你將APP_ABI := armeabi armeabi-v7a mips x86,那么android工程下邊的 libs 里邊會出現 armeabi armeabi-v7a mips x86 這四個目錄下會分別生成 4個.so文件。程序在Android手機運行時,根據手機自身CPU芯片不同,去選擇調用相應的.so文件。

Android.mk:向生成系統描述你的源代碼

----------start----------
# Copyright (C) 2009 The Android Open Source Project
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := hello-jni
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)

----------end----------
//LOCAL_PATH := $(call my-dir)  給出當前文件的路徑,my-dir返回當前Android.mk所在目錄的路徑  
//include $(CLEAR_VARS)  指定讓GNU MAKEFILE為你清除許多LOCAL_XXX變量。CLEAR_VARS:指向一個編譯腳本。這個必須在開始一個新模塊之前包含  
//LOCAL_MODULE := hellojni_shared 這個模塊的名字,它必須是唯一的,而且不能包含空格  
//LOCAL_MODULE_FILENAME := libhellojni 設置你的模塊的二進制文件的名稱,獨立于LOCAL_MODULE  
//LOCAL_SRC_FILES := hellocpp/main.cpp \ ../../Classes/AppDelegate.cpp
//include $(BUILD_SHARED_LIBRARY). BUILD_SHARED_LIBRARY表示編譯生成共享庫(動態庫),是編譯系統提供的變量,指向一個GNU Makefile腳本,負責收集自從上次調用'include $(CLEAR_VARS)'以來,定義在LOCAL_XXX變量中的所有信息,并且決定編譯什么,如何正確地去做。

Application.mk:描述你的工程下的native模,一般在$PROJECT/jni/,這樣可以被ndk-build腳本。這個文件可以不寫。

//1.指定application里要鏈接的標準c++庫  
APP_STL := gnustl_static  
//2.編譯選項  
APP_CPPFLAGS := -frtti -DCC_ENABLE_CHIPMUNK_INTEGRATION=1 -DCOCOS2D_DEBUG=1 
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容