成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android兼容性 | NDK工具集更新須知

移動(dòng)開發(fā) Android
受 Android 平臺(tái)其他改進(jìn)的影響,Android M 和 N 中的動(dòng)態(tài)鏈接器對(duì)于編寫整潔且具有跨平臺(tái)兼容性的本機(jī)代碼提出了更為嚴(yán)格的要求;滿足這些要求的本機(jī)代碼才能順利完成加載。為確保平穩(wěn)過渡到較新的 Android 版本,應(yīng)用的本機(jī)代碼必須遵循這些規(guī)則和建議。

Android兼容性 | NDK工具集更新須知

受 Android 平臺(tái)其他改進(jìn)的影響,Android M 和 N 中的動(dòng)態(tài)鏈接器對(duì)于編寫整潔且具有跨平臺(tái)兼容性的本機(jī)代碼提出了更為嚴(yán)格的要求;滿足這些要求的本機(jī)代碼才能順利完成加載。為確保平穩(wěn)過渡到較新的 Android 版本,應(yīng)用的本機(jī)代碼必須遵循這些規(guī)則和建議。

下面,我們將重申并詳細(xì)說明與本機(jī)代碼加載有關(guān)的各項(xiàng)變更及其影響,以及您可以采取哪些措施來避免出現(xiàn)問題。

所需工具:在 NDK 中,每個(gè)架構(gòu)都有一個(gè) <arch>-linux-android-readelf 二進(jìn)制文件(如 arm-linux-androideabi-readelf 或 i686-linux-android-readelf,位于 toolchains/ 下),但您可以對(duì)任何架構(gòu)使用 readelf,因?yàn)槲覀儗⒅贿M(jìn)行基本檢查。在 Linux 上,您需要為 readelf 安裝“binutils”程序包,為 scanelf 安裝“pax-utils”程序包。

私有 API(從 API 24 開始實(shí)施)

本機(jī)庫只能使用公共 API,且不得鏈接到非 NDK 平臺(tái)庫。此規(guī)則從 API 24 開始實(shí)施,此后應(yīng)用便無法再加載非 NDK 平臺(tái)庫。此規(guī)則由動(dòng)態(tài)鏈接器執(zhí)行,因此無論代碼使用何種方式加載,都無法訪問非公共庫:System.loadLibrary(...)、DT_NEEDED 條目以及直接調(diào)用 dlopen(...) 都會(huì)同樣失敗。

對(duì)于各項(xiàng)更新,用戶獲得的應(yīng)用體驗(yàn)應(yīng)該是一致的,而開發(fā)者應(yīng)不必進(jìn)行緊急更新應(yīng)用以應(yīng)對(duì)平臺(tái)變更。因此,我們建議不要使用私有 C/C++ 符號(hào)。所有 Android 設(shè)備都必須通過的兼容性測(cè)試套件 (CTS) 并不包含對(duì)私有符號(hào)進(jìn)行測(cè)試。此類符號(hào)可能不存在,也可能會(huì)采用不同的行為方式。這可能導(dǎo)致使用私有符號(hào)的應(yīng)用在某些設(shè)備上,或在未來發(fā)布的新版本系統(tǒng)中無法使用。當(dāng) Android 6.0 Marshmallow 從 OpenSSL 切換到 BoringSSL 后,很多開發(fā)者都發(fā)現(xiàn)了這種問題。

為了減少這種過渡對(duì)用戶的影響,我們確定了 Google Play 上安裝量最大的應(yīng)用中頗為常用且我們短期內(nèi)仍可提供支持的一些庫(包括 libandroid_runtime.so、libcutils.so、libcrypto.so 和 libssl.so)。為了給您留出更多時(shí)間進(jìn)行過渡,我們會(huì)暫時(shí)支持這些庫;因此,如果看到表示您的代碼在將來發(fā)布的版本中會(huì)無效的警告信息,請(qǐng)立即予以更正!

  1. $ readelf --dynamic libBroken.so | grep NEEDED 
  2.  0x00000001 (NEEDED)                     Shared library: [libnativehelper.so] 
  3.  0x00000001 (NEEDED)                     Shared library: [libutils.so] 
  4.  0x00000001 (NEEDED)                     Shared library: [libstagefright_foundation.so] 
  5.  0x00000001 (NEEDED)                     Shared library: [libmedia_jni.so] 
  6.  0x00000001 (NEEDED)                     Shared library: [liblog.so] 
  7.  0x00000001 (NEEDED)                     Shared library: [libdl.so] 
  8.  0x00000001 (NEEDED)                     Shared library: [libz.so] 
  9.  0x00000001 (NEEDED)                     Shared library: [libstdc++.so] 
  10.  0x00000001 (NEEDED)                     Shared library: [libm.so] 
  11.  0x00000001 (NEEDED)                     Shared library: [libc.so]  

潛在問題:從 API 24 開始,動(dòng)態(tài)鏈接器將無法加載私有庫,從而導(dǎo)致應(yīng)用無法加載。

解決方案:重寫本機(jī)代碼,使其僅依賴公共 API。短期解決方案是:將沒有復(fù)雜依存關(guān)系的平臺(tái)庫 (libcutils.so) 復(fù)制到項(xiàng)目;長期解決方案是將相關(guān)代碼復(fù)制到項(xiàng)目樹。SSL/Media/JNI internal/binder API 不得通過本機(jī)代碼訪問。必要時(shí),本機(jī)代碼應(yīng)調(diào)用適當(dāng)?shù)墓?Java API 方法。

NDK 的 platforms/android-API/usr/lib 下列出了所有的公共庫。

注意:SSL/crypto 是一種特殊情況,應(yīng)用不得直接使用平臺(tái) libcrypto 和 libssl 庫,即使在較早版本的平臺(tái)上也不可以。所有應(yīng)用都應(yīng)使用 GMS 安全提供程序,以確保應(yīng)用免遭已知漏洞攻擊。

缺少節(jié)標(biāo)頭(從 API 24 開始實(shí)施)

每個(gè) ELF 文件的節(jié)標(biāo)頭中都包含附加信息。現(xiàn)在,文件中必須有這些節(jié)標(biāo)頭,因?yàn)閯?dòng)態(tài)鏈接器要使用它們來進(jìn)行健全性檢查。有些開發(fā)者嘗試通過刪除這些節(jié)標(biāo)頭對(duì)二進(jìn)制文件進(jìn)行混淆處理,防止遭到反向工程。(這樣做實(shí)際上并沒有用,因?yàn)榭梢允褂霉ぞ邅碇亟ㄒ褎h除的信息,而這類工具到處都有。)

  1. $ readelf --header libBroken.so | grep 'section headers' 
  2.   Start of section headers:          0 (bytes into file) 
  3.   Size of section headers:           0 (bytes) 
  4.   Number of section headers:         0 
  5.  

解決方案:從您的版本中移除用于刪除節(jié)標(biāo)頭的額外步驟。

文本重定位(從 API 23 開始實(shí)施)

從 API 23 開始,共享對(duì)象不得包含文本重定位。也就是說,必須按原樣加載代碼,不得對(duì)其進(jìn)行修改。這種方法可縮短加載時(shí)間并提高安全性。

文本重定位的常見原因是使用了與非位置無關(guān)的手寫編譯器。這種情況并不常見。請(qǐng)使用我們的文檔中所述的 scanelf 工具進(jìn)一步診斷:

  1. $ scanelf -qT libTextRel.so 
  2.  
  3. libTextRel.so: (memory/data?) [0x15E0E2] in (optimized out: previous simd_broken_op1) [0x15E0E0] 
  4.  
  5. libTextRel.so: (memory/data?) [0x15E3B2] in (optimized out: previous simd_broken_op2) [0x15E3B0] 
  6.  
  7. [skipped the rest]  

如果您沒有可用的 scanelf 工具,可以改用 readelf 進(jìn)行基本檢查,查找 TEXTREL 條目或 TEXTREL 標(biāo)記。查找其中一項(xiàng)就已足夠。(TEXTREL 條目對(duì)應(yīng)的值無關(guān)緊要且通常為 0,存在 TEXTREL 條目即表明 .so 包含文本重定位)。以下示例中同時(shí)存在這兩種指示符:

注意:從技術(shù)上來講,可能存在帶有 TEXTREL 條目/標(biāo)記卻不包含任何實(shí)際文本重定位的共享對(duì)象。NDK 中不會(huì)出現(xiàn)這種情況,但如果您要自行生成 ELF 文件,請(qǐng)確保不要生成聲明包含文本重定位的 ELF 文件,因?yàn)?Android 動(dòng)態(tài)鏈接器信任該條目/標(biāo)記。

潛在問題:重定位會(huì)強(qiáng)制使代碼頁面可寫入,并會(huì)增加內(nèi)存中的臟頁數(shù)量,這非常浪費(fèi)內(nèi)存。從 Android K (API 19) 開始,動(dòng)態(tài)鏈接器發(fā)布了有關(guān)文本重定位的警告,而在 API 23 及更高版本中,它拒絕加載包含文本重定位的代碼。

解決方案:重寫編譯器使其與位置無關(guān),以確保不需要任何文本重定位。有關(guān)詳細(xì)信息,請(qǐng)查看 Gentoo 文檔。

無效的 DT_NEEDED 條目(從 API 23 開始實(shí)施)

雖然庫依賴項(xiàng)(ELF 標(biāo)頭中的 DT_NEEDED 條目)可以是絕對(duì)路徑,但在 Android 平臺(tái)上卻毫無意義,因?yàn)槟鸁o法控制系統(tǒng)將在何處安裝庫。DT_NEEDED 條目應(yīng)與所需庫的 SONAME 相同,將在運(yùn)行時(shí)查找?guī)斓娜蝿?wù)留給動(dòng)態(tài)鏈接器。

在 API 23 之前,Android 的動(dòng)態(tài)鏈接器在查找所需庫時(shí)會(huì)忽略完整路徑,僅使用基本名稱(最后一個(gè)“/”之后的部分)。從 API 23 開始,運(yùn)行時(shí)鏈接器將完全遵循 DT_NEEDED,因此,如果設(shè)備的特定位置不存在庫,鏈接器將無法加載相應(yīng)庫。

更糟的是,有些構(gòu)建系統(tǒng)存在漏洞,這會(huì)導(dǎo)致它們插入指向構(gòu)建主機(jī)上的文件的 DT_NEEDED 條目,而在設(shè)備上卻無法找到相應(yīng)文件。

  1. $ readelf --dynamic libSample.so | grep NEEDED 
  2.  0x00000001 (NEEDED)                     Shared library: [libm.so] 
  3.  0x00000001 (NEEDED)                     Shared library: [libc.so] 
  4.  0x00000001 (NEEDED)                     Shared library: [libdl.so] 
  5.  0x00000001 (NEEDED)                     Shared library: 
  6. [C:\Users\build\Android\ci\jni\libBroken.so] 
  7.  

潛在問題:在 API 23 之前使用的是 DT_NEEDED 條目的基本名稱,但從 API 23 開始,Android 運(yùn)行時(shí)將嘗試使用指定路徑加載庫,但設(shè)備上卻不存在該路徑。有些已損壞的第三方工具鏈/構(gòu)建系統(tǒng)使用的是構(gòu)建主機(jī)而非 SONAME 上的路徑。

解決方案:確保所有所需的庫僅由 SONAME 引用。最好讓運(yùn)行時(shí)鏈接器查找和加載這些庫,因?yàn)閹煸诓煌O(shè)備上的位置可能有所不同。

缺少 SONAME(從 API 23 開始使用)

每個(gè) ELF 共享對(duì)象(“本機(jī)庫”)都必須具備 SONAME(共享對(duì)象名稱)屬性。NDK 工具鏈會(huì)默認(rèn)添加此屬性,如果此屬性不存在,則表明備用工具鏈配置有誤或構(gòu)建系統(tǒng)中存在錯(cuò)誤配置。缺少 SONAME 可能會(huì)導(dǎo)致運(yùn)行時(shí)問題,例如加載錯(cuò)誤的庫:缺少此屬性時(shí)會(huì)改為使用文件名。

  1. $ readelf --dynamic libWithSoName.so | grep SONAME 
  2.  
  3. 0x0000000e (SONAME) Library soname: [libWithSoName.so] 
  4.  
  5.  

潛在問題:命名空間沖突可能會(huì)導(dǎo)致在運(yùn)行時(shí)加載錯(cuò)誤的庫,進(jìn)而導(dǎo)致在未找到所需符號(hào)時(shí)或您嘗試使用非預(yù)期且不兼容 ABI 的庫時(shí)系統(tǒng)崩潰。

解決方案:最新版 NDK 會(huì)默認(rèn)生成正確的 SONAME。請(qǐng)確保您使用的是最新版 NDK,且未將構(gòu)建系統(tǒng)配置為生成不正確的 SONAME 條目(使用 -soname 鏈接器選項(xiàng))。

請(qǐng)注意,使用最新版 NDK 構(gòu)建的整潔的跨平臺(tái)代碼應(yīng)當(dāng)可以在 Android N 上正常運(yùn)行。我們建議您修改本機(jī)代碼構(gòu)建配置,以便生成正確的二進(jìn)制文件。 

 

 

 

Android 的兼容性一直是很多開發(fā)者所關(guān)心的問題,我們將持續(xù)關(guān)注 Android 兼容性的變化,并發(fā)布一系列相關(guān)文章幫助大家及時(shí)了解。如果您在使用 NDK 工具集的過程中發(fā)現(xiàn)了我們尚未收錄的 Android 兼容性問題,歡迎留言,我們將盡力尋找答案,并在新的文章中給予解答。

責(zé)任編輯:龐桂玉 來源: 安卓開發(fā)精選
相關(guān)推薦

2010-02-26 08:53:03

Windows 7兼容性更新

2023-04-17 19:43:54

兼容性測(cè)試軟件測(cè)試

2009-03-07 09:49:07

Windows 7兼容性

2009-02-25 09:22:01

Windows 7Client Beta兼容性

2010-08-09 10:22:28

2010-12-23 14:01:42

2010-08-10 09:59:28

Office 2010兼容性OMPM

2010-06-23 20:21:42

微軟Windows 7補(bǔ)丁

2011-08-16 15:17:44

IOS SDK

2021-12-27 16:22:19

鴻蒙HarmonyOS應(yīng)用

2023-03-24 07:31:58

Oracle兼容性產(chǎn)品

2010-03-04 11:13:53

Android系統(tǒng)手機(jī)

2010-03-05 17:09:18

2012-05-14 11:29:00

ACT

2010-08-26 13:37:21

Windows 7補(bǔ)丁

2009-08-07 08:42:28

Windows 7兼容性檢查

2021-07-26 12:18:02

FreeBSDLinux開發(fā)者

2011-04-07 09:18:10

AndroidiOS蘋果

2009-12-09 15:16:33

2009-09-24 08:42:17

Windows 7兼容性
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 欧美激情在线精品一区二区三区 | 久久国产精品一区二区三区 | 精品一区二区久久久久久久网站 | 中文字幕亚洲欧美 | 老牛嫩草一区二区三区av | 精品一区二区三区在线视频 | 天堂一区二区三区四区 | 91黄色片免费看 | 亚洲444eee在线观看 | 97国产在线观看 | 国产精品a久久久久 | 在线观看黄色 | 日韩精品视频在线播放 | 国产精品久久久久久久午夜 | 欧美日韩精品一区 | 一区二区精品电影 | 91精品一区二区三区久久久久久 | 精精国产xxxx视频在线播放 | 中文字幕一区二区三区四区 | 日本成年免费网站 | 久久久久国产精品一区二区 | 免费一区二区在线观看 | 色偷偷噜噜噜亚洲男人 | 三级视频久久 | 国产精品视频一二三 | 欧美国产一区二区三区 | 亚洲成人免费电影 | 国产色婷婷精品综合在线播放 | 精品国产欧美一区二区 | www成人啪啪18| 黄色大片在线播放 | 999视频在线播放 | 视频在线一区二区 | 成人免费观看视频 | 国产a一区二区 | 中文字幕亚洲视频 | 美女国产精品 | 国产精品三级久久久久久电影 | 亚洲手机在线 | 7777在线| 日韩在线视频一区 |