在NDK中使用 C++ 時,請使用最新 NDK,並選擇使用 libc++ 共享STL 做爲 C++ STL,這樣可使多個 so 共享一個 C++ STL,由於使用靜態STL將會在每一個 so 庫中出現重複代碼,增長應用大小,而且因爲全局數據和靜態構造函數在內的 STL 將同時存在於兩個庫中。此應用的運行時行爲未定義,所以在實際運行過程當中,應用會常常崩潰。例如:內存在一個庫中分配,而在另外一個庫中釋放,從而致使內存泄漏或堆損壞。java
在 Application.mk 中添加android
APP_STL := c++_shared
複製代碼
在 build.gradle 中添加ios
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
}
}
複製代碼
使用 c++_shared 編譯後 aar 中將附帶 libc++_shared.so,若是有多個aar 都附帶了 libc++_shared.so,將致使APP工程中編譯不過,此時能夠採起下面兩種辦法:c++
packagingOptions {
pickFirst 'lib/*/libc++_shared.so'
}
複製代碼
libraryVariants.all { variant ->
def bundleTask = variant.packageLibrary
def reBundleTask = tasks.create("reBundle${variant.name.capitalize()}Aar", Zip) {
def dir = bundleTask.destinationDir
def path = bundleTask.archivePath
def name = bundleTask.archiveName
archiveName name + ".bak"
destinationDir dir
from(zipTree(path)) {
exclude "jni/*/libc++_shared.so"
}
doLast {
delete path
file("$dir/$name" + ".bak").renameTo(path)
}
}
bundleTask.finalizedBy reBundleTask
variant.assemble.dependsOn reBundleTask
}
複製代碼
若是使用 GCC 能夠 -Os 打開優化,若是使用 Clang 能夠 -Oz 打開優化小程序
在 Android.mk 中添加api
LOCAL_CFLAGS += -Os -Oz
LOCAL_CPPFLAGS += -Os -Oz
複製代碼
在 build.gradle 中添加bash
externalNativeBuild {
cmake {
cFlags "-Os -Oz"
cppFlags "-Os -Oz"
}
}
複製代碼
-fvisibility=hidden
複製代碼
隱藏elf符號表,能夠減小 so 文件大小,提高性能 注意:須要在提供給 java 層暴露的JNI函數能夠 在方法上添加 JNIEXPORT 宏或者添加屬性 attribute ((visibility ("default")))函數
-fvisibility-inlines-hidden
複製代碼
隱藏全部內聯函數,從而減少導出符號表的大小,既能縮減文件的大小,還能提升運行性能性能
在 Android.mk 中添加gradle
LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_CPPFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
複製代碼
externalNativeBuild {
cmake {
cFlags "-fvisibility=hidden"
cppFlags "-fvisibility=hidden -fvisibility-inlines-hidden"
}
}
複製代碼
使用 --gc-section 編譯選項減少程序體積
解決方案
在 Android.mk 中添加
LOCAL_CPPFLAGS += -ffunction-sections -fdata-sections
LOCAL_CFLAGS += -ffunction-sections -fdata-sections
LOCAL_LDFLAGS += -Wl,--gc-sections
複製代碼
在 build.gradle 中添加
externalNativeBuild {
cmake {
cFlags "-ffunction-sections -fdata-sections"
cppFlags "-ffunction-sections -fdata-sections"
}
}
複製代碼
在C++ 中使用異常和 RTTI 會顯著增長文件大小,所以儘可能不要在 C++中 使用異常和 RTTI,若是代碼中沒有使用到 異常和 RTTI 請刪除相關 feature 和 flags
從 LOCAL_CPP_FEATURES 中 刪除 exceptions 和 rtti
從 APP_CPPFLAGS 中 刪除 -frtti 和 -fexceptions
從 LOCAL_CPPFLAGS 中 刪除 -frtti 和 -fexceptions
複製代碼
刪除 cppFlags "-frtti"
刪除 cppFlags "-fexceptions"
複製代碼
儘可能不要在 C++ 代碼中使用 iostream,如:
#include<iostream>
std::cout << "test" <<std::endl;
複製代碼
其餘相似用法:std::cin,std::cout,std::cerr,std::clog,std::wcin,std::wcout,std::wcerr,std::wclog
這樣沒有什麼做用而且會顯著增長 so 文件大小
刪除 iostream 相關代碼調用,若是有打日誌須要可使用 __android_log_print
#define LOG_TAG "native_log"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
複製代碼