Android app中的so庫和CPU架構

一.android目前有幾種cpu架構?

早期的Android系統幾乎只支持ARMv5的CPU架構,目前支持七種CPU架構:ARMv5,ARMv7 (從2010年起),x86 (從2011年起),MIPS (從2012年起),ARMv8,MIPS64和x86_64 (從2014年起),每一種都關聯着一個相應的ABI。對應的ABI依次是:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64,對應Android app工程中so庫的不一樣目錄。java

二.須要每種架構的so庫都放全嗎?

看so庫的來源,是第三方提供的,仍是本身開發的。android

1.假若是集成第三方sdk,最好將它提供的都拷貝到項目中。(可是基本不多提供全面so庫支持的)web

2.假若是本身開發的 ,那就根據本身的狀況,編譯出對應版本的so庫。架構

三.每種機型只能加載一種適合本身版本的so庫嗎?

不少設備都支持多於一種的ABI。例如ARM64和x86設備也能夠同時運行armeabi-v7a和armeabi的二進制包。但最好是針對特定平臺提供相應平臺的二進制包,這種狀況下運行時就少了一個模擬層(例如x86設備上模擬arm的虛擬層),從而獲得更好的性能(歸功於最近的架構更新,例如硬件fpu,更多的寄存器,更好的向量化等)。app

四.如何查看當前設備支持那些版本的so庫?

能夠經過Build.SUPPORTED_ABIS獲得根據偏好排序的設備支持的ABI列表。但你不該該從你的應用程序中讀取它,由於Android包管理器安裝APK時,若是在對應的lib/ABI目錄中存在.so文件的話,會自動選擇APK包中爲對應系統ABI預編譯好的.so文件。函數

五.不一樣的開發環境so庫應該放在哪裏?

  • Android Studio工程放在jniLibs/ABI目錄中(固然也能夠經過在build.gradle文件中的設置jniLibs.srcDir屬性本身指定)性能

  • Eclipse工程放在libs/ABI目錄中(這也是ndk-build命令默認生成.so文件的目錄)gradle

  • AAR壓縮包中位於jni/ABI目錄中(.so文件會自動包含到引用AAR壓縮包的APK中)優化

  • 最終APK文件中的lib/ABI目錄中ui

  • 經過PackageManager安裝後,在小於Android 5.0的系統中,.so文件位於app的nativeLibraryPath目錄中;在大於等於Android 5.0的系統中,.so文件位於app的nativeLibraryRootDir/CPU_ARCH目錄中。

六.爲何通常的項目中只看到armeabi文件夾?

由於全部的x86/x86_64/armeabi-v7a/arm64-v8a設備都支持armeabi架構的.so文件。  mips和mips64是不支持armeabi架構的.so文件的,不過MIPS是一種高性能的嵌入式CPU構架,其出發點是高性能,主要用於路由器、貓等,基本在手機上不使用

七.是否是隻放一種armeabi就夠了?

事實上並非:這不僅影響到函數庫的性能和兼容性。x86設備可以很好的運行ARM類型函數庫,但並不保證100%不發生crash,特別是對舊設備。64位設備(arm64-v8a, x86_64, mips64)可以運行32位的函數庫,可是以32位模式運行,在64位平臺上運行32位版本的ART和Android組件,將丟失專爲64位優化過的性能(ART,webview,media等等)。

八.不一樣Android版本系統拷貝不一樣目錄so庫的差別

工程項目中,有armeabi 、armeabi-v7a兩個文件夾,而兩個文件夾中的庫文件不同,編譯運行的時候,報錯java.lang.UnsatisfiedLinkError: dalvik.system.PathClassLoader

緣由分析

在android APK的根目錄有一個libs文件夾,此文件夾下包含了armeabi 、armeabi-v7a兩個文件夾,有時候會有x86的;通常c代碼編譯成的各類.so庫就會放在這兩個文件夾中。

armeabi和armeabi-7a是表示cpu的類型,通常的手機或平板都是用arm的cpu,armeabi是針對普通的或舊的arm cpu,armeabi通用性強,但速度慢;armeabi-v7a是針對有浮點運算或高級擴展功能的arm cpu,速度快

android的APP在安裝時,會將APP中的so庫拷貝到一個指定的目錄(ApplicationInfo.nativeLibraryDir),運行時就在這個指定的目錄下查找對應的so庫。查找不到則會報錯。

  1. 在android4.4如下版本的安裝過程當中的,是先把全部so庫所有尋找出來,而後優先列出cpu類型(經過ro.product.cpu.abi屬性得到)目錄下的so庫,若是有其餘的cpu類型下有跟手機cpu類型名稱不一致的so庫,則會將兼容cpu架構(經過ro.product.cpu.abi2屬性得到)的另外的庫也列出來。將列出來so庫所有拷貝的系統指定目錄,以供運行時加載。 即在android4.4如下版本,一個so庫只要在 ro.product.cpu.abi和ro.product.cpu.abi2屬性目錄下至少存在一個就能夠了。在android4.4如下的arm架構的設備 ro.product.cpu.abi的屬性一般是armeabi-v7a, ro.product.cpu.abi2的屬性值是armeabi,而且armeabi-v7a設備必定兼容armeabi。但不排除某些設備的ro.product.cpu.abi的屬性爲armeabi。

  2. 在android5.0及以上,因爲增長了arm64的支持,app安裝時的so庫拷貝代碼也修改了。修改爲只拷貝一個最合適的目錄下的so庫到系統指定目錄。 在arm架構下,64位cpu的優先級是arm64-v8a > armeabi-v7a > armeabi,32位cpu的優先級是armeabi-v7a > armeabi ,優先級可經過ro.product.cpu.abilist屬性查看。因爲android5.0是拷貝總體目錄,因此在每個目錄下的,都必需要有完整的so,即全部app須要so庫都要有。例如64位的cpu的設備上,
    若是app目錄裏存在arm64-v8a子目錄,則只拷貝該目錄下的so庫,其餘目錄的so,即便名稱不同,也不拷貝,若是arm64-v8a子目錄的so庫不全,則會報錯。

解決方法

  1. apk中要麼增長armeabi文件夾,須要注意的是,假如增長armeabi文件夾,armeabi-v7a裏面的so庫必定須要所有拷貝過來,不然仍是會報錯。

  2. 能夠刪除了armeabi-v7a文件夾,保留armeabi文件夾。

相關文章
相關標籤/搜索