Android 7.0 開(kāi)發(fā)者版本
Android 7.0 Nougat 為用戶和開(kāi)發(fā)者引入多種新功能。
請(qǐng)務(wù)必查閱 Android 7.0 行為變更以了解平臺(tái)變更可能影響您的應(yīng)用的領(lǐng)域脊串。
多窗口支持
在 Android 7.0 中牛隅,我們?yōu)樵撈脚_(tái)引入了一個(gè)新的而且非常需要的多任務(wù)處理功能 — 多窗口支持攀例。
現(xiàn)在嘉汰,用戶可以一次在屏幕上打開(kāi)兩個(gè)應(yīng)用羡亩。
- 在運(yùn)行 Android 7.0 的手機(jī)和平板電腦上摩疑,用戶可以并排運(yùn)行兩個(gè)應(yīng)用,或者處于分屏模式時(shí)一個(gè)應(yīng)用位于另一個(gè)應(yīng)用之上畏铆。用戶可以通過(guò)拖動(dòng)兩個(gè)應(yīng)用之間的分隔線來(lái)調(diào)整應(yīng)用未荒。
- 在 Android TV 設(shè)備上,應(yīng)用可以將自身置于畫(huà)中畫(huà)模式及志,從而讓它們可以在用戶瀏覽或與其他應(yīng)用交互時(shí)繼續(xù)顯示內(nèi)容片排。
多窗口支持為您提供新的吸引用戶方式,特別是在平板電腦和其他更大屏幕的設(shè)備上速侈。您甚至可以在您的應(yīng)用中啟用拖放率寡,從而使用戶可以方便地將內(nèi)容拖放到您的應(yīng)用或從其中拖出內(nèi)容—這是一個(gè)非常好的增強(qiáng)用戶體驗(yàn)的方式。
向您的應(yīng)用添加多窗口支持并配置多窗口顯示的處理方式非常簡(jiǎn)單倚搬。例如冶共,您可以指定您的 Activity 允許的最小尺寸,從而防止用戶將 Activity 調(diào)整到該尺寸以下每界。您還可以為應(yīng)用停用多窗口顯示捅僵,這可確保系統(tǒng)將僅以全屏模式顯示應(yīng)用。
如需了解詳細(xì)信息眨层,請(qǐng)參閱多窗口支持開(kāi)發(fā)者文檔庙楚。
通知增強(qiáng)功能
在 Android 7.0 中,我們重新設(shè)計(jì)了通知趴樱,使其更易于使用并且速度更快馒闷。部分變更包括:
- 模板更新:我們正在更新通知模板,新強(qiáng)調(diào)了英雄形象和化身叁征。開(kāi)發(fā)者將能夠充分利用新模板纳账,只需進(jìn)行少量的代碼調(diào)整。
-
消息傳遞樣式自定義:您可以自定義更多與您的使用
MessagingStyle
類的通知相關(guān)的用戶界面標(biāo)簽捺疼。您可以配置消息疏虫、會(huì)話標(biāo)題和內(nèi)容視圖。 - 捆綁通知:系統(tǒng)可以將消息組合在一起(例如,按消息主題)并顯示組卧秘。用戶可以適當(dāng)?shù)剡M(jìn)行拒絕或歸檔等操作尤蛮。如果您已實(shí)現(xiàn) Android Wear 的通知,那么您已經(jīng)很熟悉此模式斯议。
- 直接回復(fù):對(duì)于實(shí)時(shí)通信應(yīng)用,Android 系統(tǒng)支持內(nèi)聯(lián)回復(fù)醇锚,以便用戶可以直接在通知界面中快速回復(fù)短信哼御。
- 自定義視圖:兩個(gè)新的 API 讓您在通知中使用自定義視圖時(shí)可以充分利用系統(tǒng)裝飾元素,如通知標(biāo)題和操作焊唬。
要了解如何實(shí)現(xiàn)新功能的信息恋昼,請(qǐng)參閱通知指南。
配置文件指導(dǎo)的 JIT/AOT 編譯
在 Android 7.0 中赶促,我們添加了即時(shí) (JIT) 編譯器液肌,對(duì) ART 進(jìn)行代碼分析,讓它可以在應(yīng)用運(yùn)行時(shí)持續(xù)提升 Android 應(yīng)用的性能鸥滨。JIT 編譯器對(duì) Android 運(yùn)行組件當(dāng)前的 Ahead of Time (AOT) 編譯器進(jìn)行了補(bǔ)充嗦哆,有助于提升運(yùn)行時(shí)性能,節(jié)省存儲(chǔ)空間婿滓,加快應(yīng)用更新和系統(tǒng)更新速度老速。
配置文件指導(dǎo)的編譯讓 Android 運(yùn)行組件能夠根據(jù)應(yīng)用的實(shí)際使用以及設(shè)備上的情況管理每個(gè)應(yīng)用的 AOT/JIT 編譯。例如凸主,Android 運(yùn)行組件維護(hù)每個(gè)應(yīng)用熱方法的配置文件橘券,并且可以預(yù)編譯和緩存這些方法以實(shí)現(xiàn)最佳性能。對(duì)于應(yīng)用的其他部分卿吐,在實(shí)際使用之前不會(huì)進(jìn)行編譯旁舰。
除提升應(yīng)用的關(guān)鍵部分的性能外,配置文件指導(dǎo)的編譯還有助于減少整個(gè) RAM 占用嗡官,包括關(guān)聯(lián)的二進(jìn)制文件箭窜。此功能對(duì)于低內(nèi)存設(shè)備非常尤其重要。
Android 運(yùn)行組件在管理配置文件指導(dǎo)的編譯時(shí)衍腥,可最大程度降低對(duì)設(shè)備電池的影響绽快。僅當(dāng)設(shè)備處于空閑狀態(tài)和充電時(shí)才進(jìn)行編譯,從而可以通過(guò)提前執(zhí)行該工作節(jié)約時(shí)間和省電紧阔。
快速的應(yīng)用安裝路徑
Android 運(yùn)行組件的 JIT 編譯器最實(shí)際的好處之一是應(yīng)用安裝和系統(tǒng)更新的速度坊罢。即使在 Android 6.0 中需要幾分鐘進(jìn)行優(yōu)化和安裝的大型應(yīng)用,現(xiàn)在只需幾秒鐘就可以完成安裝擅耽。系統(tǒng)更新也變得更快活孩,因?yàn)槭∪チ藘?yōu)化步驟。
隨時(shí)隨地低電耗模式...
Android 6.0 推出了低電耗模式乖仇,即設(shè)備處于空閑狀態(tài)時(shí)憾儒,通過(guò)推遲應(yīng)用的 CPU 和網(wǎng)絡(luò)活動(dòng)以實(shí)現(xiàn)省電目的的系統(tǒng)模式询兴,例如,設(shè)備放在桌上或抽屜里時(shí)起趾。
現(xiàn)在诗舰,在 Android 7.0 中,低電耗模式又前進(jìn)了一步训裆,隨時(shí)隨地可以省電眶根。只要屏幕關(guān)閉了一段時(shí)間,且設(shè)備未插入電源边琉,低電耗模式就會(huì)對(duì)應(yīng)用使用熟悉的 CPU 和網(wǎng)絡(luò)限制属百。這意味著用戶即使將設(shè)備放入口袋里也可以省電。
低電耗模式現(xiàn)在應(yīng)用限制以延長(zhǎng)電池壽命变姨,即使設(shè)備未處于靜止?fàn)顟B(tài)族扰。
屏幕關(guān)閉片刻后,設(shè)備在使用電池時(shí)定欧,低電耗模式將限制網(wǎng)絡(luò)訪問(wèn)渔呵,同時(shí)延遲作業(yè)和同步。在短暫的維護(hù)時(shí)間范圍后砍鸠,其允許應(yīng)用訪問(wèn)網(wǎng)絡(luò)厘肮,并執(zhí)行延遲的作業(yè)/同步。打開(kāi)屏幕或?qū)⒃O(shè)備插入電源會(huì)使設(shè)備退出低電耗模式睦番。
當(dāng)設(shè)備再次處于靜止?fàn)顟B(tài)時(shí)类茂,屏幕關(guān)閉且使用電池一段時(shí)間,低電耗模式針對(duì) [PowerManager.WakeLock](https://developer.android.com/reference/android/os/PowerManager.WakeLock)
托嚣、[AlarmManager](https://developer.android.com/reference/android/app/AlarmManager)
警報(bào)和 GPS/WLAN 掃描應(yīng)用完整 CPU 和網(wǎng)絡(luò)限制巩检。
無(wú)論設(shè)備是否處于運(yùn)動(dòng)狀態(tài),將應(yīng)用調(diào)整到低電耗模式的最佳做法均相同示启,因此兢哭,如果您已更新應(yīng)用以妥善處理低電耗模式,則一切就緒夫嗓。如果不是迟螺,請(qǐng)立即開(kāi)始將應(yīng)用調(diào)整到低電耗模式。
Project Svelte:后臺(tái)優(yōu)化
Project Svelte 在持續(xù)改善舍咖,以最大程度減少生態(tài)系統(tǒng)中一系列 Android 設(shè)備中系統(tǒng)和應(yīng)用使用的 RAM矩父。在 Android 7.0 中,Project Svelte 注重優(yōu)化在后臺(tái)中運(yùn)行應(yīng)用的方式排霉。
后臺(tái)處理是大多數(shù)應(yīng)用的一個(gè)重要部分窍株。處理得當(dāng),可讓您實(shí)現(xiàn)非常棒的用戶體驗(yàn) — 即時(shí)、快速和情境感知球订。如果處理不得當(dāng)后裸,后臺(tái)處理會(huì)毫無(wú)必要地消耗 RAM(和電池),同時(shí)影響其他應(yīng)用的系統(tǒng)性能冒滩。
自 Android 5.0 發(fā)布以來(lái)微驶,[JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler)
已成為執(zhí)行后臺(tái)工作的首選方式,其工作方式有利于用戶开睡。應(yīng)用可以在安排作業(yè)的同時(shí)允許系統(tǒng)基于內(nèi)存因苹、電源和連接情況進(jìn)行優(yōu)化。JobScheduler 可實(shí)現(xiàn)控制和簡(jiǎn)潔性士八,我們想要所有應(yīng)用都使用它。
另一個(gè)非常好的選擇是 GCMNetworkManager
(Google Play 服務(wù)的一部分)梁呈,其在舊版 Android 中提供類似的作業(yè)安排和兼容性婚度。
我們?cè)诶^續(xù)擴(kuò)展 JobScheduler
和 GCMNetworkManager
,以符合多個(gè)用例 — 例如官卡,在 Android 7.0 中蝗茁,現(xiàn)在,您可以基于內(nèi)容提供程序中的更改安排后臺(tái)工作寻咒。同時(shí)哮翘,我們開(kāi)始棄用一些較舊的模式,這些模式會(huì)降低系統(tǒng)性能毛秘,特別是低內(nèi)存設(shè)備的系統(tǒng)性能饭寺。
在 Android 7.0 中,我們刪除了三個(gè)常用隱式廣播 — [CONNECTIVITY_ACTION](https://developer.android.com/reference/android/net/ConnectivityManager#CONNECTIVITY_ACTION)
叫挟、[ACTION_NEW_PICTURE](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_PICTURE)
和[ACTION_NEW_VIDEO](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_VIDEO)
— 因?yàn)檫@些廣播可能會(huì)一次喚醒多個(gè)應(yīng)用的后臺(tái)進(jìn)程艰匙,同時(shí)會(huì)耗盡內(nèi)存和電池。如果您的應(yīng)用收到這些廣播抹恳,請(qǐng)充分利用 Android 7.0 以遷移到 JobScheduler
和相關(guān)的 API员凝。
如需了解詳情,請(qǐng)查看后臺(tái)優(yōu)化文檔奋献。
SurfaceView
Android 7.0 可同步移動(dòng)到 [SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
類健霹,此類在某些情況下提供的電池性能優(yōu)于 [TextureView](https://developer.android.com/reference/android/view/TextureView)
:在渲染視頻或 3D 內(nèi)容時(shí),包含滾動(dòng)和動(dòng)畫(huà)視頻位置的應(yīng)用在使用 [SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
時(shí)比 [TextureView](https://developer.android.com/reference/android/view/TextureView)
耗電更少瓶蚂。
[SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
類可減少屏幕合成對(duì)電池的消耗糖埋,因?yàn)樗窃趯S糜布泻铣桑c應(yīng)用窗口內(nèi)容分隔開(kāi)窃这。因此阶捆,它產(chǎn)生的中間副本少于 [TextureView](https://developer.android.com/reference/android/view/TextureView)
。
現(xiàn)在,[SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
對(duì)象的內(nèi)容位置和包含的應(yīng)用內(nèi)容同步更新洒试。這一變化導(dǎo)致的一個(gè)結(jié)果是倍奢,在畫(huà)面移動(dòng)時(shí),[SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
中播放的視頻的簡(jiǎn)單的平移或縮放不再在畫(huà)面?zhèn)让娈a(chǎn)生黑條垒棋。
從 Android 7.0 開(kāi)始卒煞,我們強(qiáng)烈建議您使用 [SurfaceView](https://developer.android.com/reference/android/view/SurfaceView)
代替 [TextureView](https://developer.android.com/reference/android/view/TextureView)
,以實(shí)現(xiàn)省電叼架。
流量節(jié)省程序
在移動(dòng)設(shè)備的整個(gè)生命周期畔裕,移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)計(jì)劃的成本通常會(huì)超出設(shè)備本身的成本。對(duì)于許多用戶而言乖订,移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)是他們想要節(jié)省的昂貴資源扮饶。
Android 7.0 推出了流量節(jié)省模式,這是一項(xiàng)新的系統(tǒng)服務(wù)乍构,有助于減少應(yīng)用使用的移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)甜无,無(wú)論是在漫游,賬單周期即將結(jié)束哥遮,還是使用少量的預(yù)付費(fèi)數(shù)據(jù)包岂丘。流量節(jié)省程序讓用戶可以控制應(yīng)用使用移動(dòng)數(shù)據(jù)網(wǎng)絡(luò)的方式,同時(shí)讓開(kāi)發(fā)者打開(kāi)流量節(jié)省程序時(shí)可以提供更多有效的服務(wù)眠饮。
用戶在 Settings 中啟用流量節(jié)省程序且設(shè)備位于按流量計(jì)費(fèi)的網(wǎng)絡(luò)上時(shí)奥帘,系統(tǒng)屏蔽后臺(tái)流量消耗,同時(shí)指示應(yīng)用在前臺(tái)盡可能使用較少的流量 — 例如仪召,通過(guò)限制用于流媒體服務(wù)的比特率寨蹋、降低圖像質(zhì)量、延遲最佳的預(yù)緩沖等方法來(lái)實(shí)現(xiàn)扔茅。用戶可以將特定應(yīng)用加入白名單以允許后臺(tái)按流量計(jì)費(fèi)的流量消耗钥庇,即使在打開(kāi)流量節(jié)省程序時(shí)也是如此。
Android 7.0 擴(kuò)展了 [ConnectivityManager](https://developer.android.com/reference/android/net/ConnectivityManager)
咖摹,以便為應(yīng)用檢索用戶的流量節(jié)省程序首選項(xiàng)并監(jiān)控首選項(xiàng)變更提供一種方式评姨。所有應(yīng)用均應(yīng)檢查用戶是否已啟用流量節(jié)省程序并努力限制前臺(tái)和后臺(tái)流量消耗。
Vulkan API
Android 7.0 將一項(xiàng)新的 3D 渲染 API Vulkan? 集成到平臺(tái)中萤晴。就像 OpenGL? ES 一樣吐句,Vulkan 是 3D 圖形和渲染的一項(xiàng)開(kāi)放標(biāo)準(zhǔn),由 Khronos Group 維護(hù)店读。
Vulkan 是完全從零開(kāi)始設(shè)計(jì)嗦枢,以最小化驅(qū)動(dòng)器中的 CPU 開(kāi)銷,并能讓您的應(yīng)用更直接地控制 GPU 操作屯断。Vulkan 還允許多個(gè)線程同時(shí)執(zhí)行工作文虏,如命令緩沖區(qū)構(gòu)建侣诺,以獲得更好的并行化。
Vulkan 開(kāi)發(fā)工具和庫(kù)都已卷入 Android 7.0DK氧秘。它們包括:
- 標(biāo)頭
- 驗(yàn)證層(調(diào)試庫(kù))
- SPIR-V 著色程序編譯器
- SPIR-V 運(yùn)行時(shí)著色器編譯庫(kù)
Vulkan 僅適用于已啟用 Vulkan 硬件的設(shè)備上的應(yīng)用年鸳,如 Nexus 5X、Nexus 6P 和 Nexus Player丸相。我們正在與合作伙伴密切合作搔确,以盡快使 Vulkan 能面向更多的設(shè)備。
如需了解詳細(xì)信息灭忠,請(qǐng)參閱 API 文檔膳算。
Quick Settings Tile API
通知欄中的快速設(shè)置圖塊。
“快速設(shè)置”通常用于直接從通知欄顯示關(guān)鍵設(shè)置和操作弛作,非常簡(jiǎn)單涕蜂。在 Android 7.0 中,我們已擴(kuò)展“快速設(shè)置”的范圍映琳,使其更加有用更方便机隙。
我們?yōu)轭~外的“快速設(shè)置”圖塊添加了更多空間,用戶可以通過(guò)向左或向右滑動(dòng)跨分頁(yè)的顯示區(qū)域訪問(wèn)它們刊头。我們還讓用戶可以控制顯示哪些“快速設(shè)置”圖塊以及顯示的位置 — 用戶可以通過(guò)拖放圖塊來(lái)添加或移動(dòng)圖塊黍瞧。
對(duì)于開(kāi)發(fā)者诸尽,Android 7.0 還添加了一個(gè)新的 API原杂,從而讓您可以定義自己的“快速設(shè)置”圖塊,使用戶可以輕松訪問(wèn)您應(yīng)用中的關(guān)鍵控件和操作您机。
對(duì)于急需或頻繁使用的控件和操作穿肄,保留“快速設(shè)置”圖塊,且不應(yīng)將其用作啟動(dòng)應(yīng)用的快捷方式际看。
定義圖塊后咸产,您可以將它們顯示給用戶,用戶可通過(guò)拖放將圖塊添加到“快速設(shè)置”仲闽。
如需了解有關(guān)創(chuàng)建應(yīng)用圖塊的信息脑溢,請(qǐng)參閱可下載的 API 參考中的文件 android.service.quicksettings.Tile
。
號(hào)碼屏蔽
Android 7.0 現(xiàn)在支持在平臺(tái)中進(jìn)行號(hào)碼屏蔽赖欣,提供框架 API屑彻,讓服務(wù)提供商可以維護(hù)屏蔽的號(hào)碼列表。默認(rèn)短信應(yīng)用顶吮、默認(rèn)手機(jī)應(yīng)用和運(yùn)營(yíng)商應(yīng)用可以對(duì)屏蔽的號(hào)碼列表進(jìn)行讀取和寫(xiě)入操作社牲。其他應(yīng)用則無(wú)法訪問(wèn)此列表救拉。
通過(guò)使號(hào)碼屏蔽成為平臺(tái)的標(biāo)準(zhǔn)功能迹辐,Android 為應(yīng)用提供一致的方式來(lái)支持廣泛的設(shè)備上的號(hào)碼屏蔽鸯绿。應(yīng)用可以利用的其他優(yōu)勢(shì)包括:
- 還會(huì)屏蔽已屏蔽的來(lái)電號(hào)碼發(fā)出的短信
- 通過(guò) Backup & Restore(備份和還原)功能可以跨重置和設(shè)備保留屏蔽的號(hào)碼
- 多個(gè)應(yīng)用可以使用相同的屏蔽號(hào)碼列表
此外,通過(guò) Android 的運(yùn)營(yíng)商應(yīng)用集成表示運(yùn)營(yíng)商可以讀取設(shè)備上屏蔽的號(hào)碼列表秆吵,并為用戶執(zhí)行服務(wù)端屏蔽,以阻止不需要的來(lái)電和短信通過(guò)任何介質(zhì)(如 VOIP 端點(diǎn)或轉(zhuǎn)接電話)到達(dá)用戶坟漱。
如需了解詳細(xì)信息竟纳,請(qǐng)參閱可下載的 API 參考中的 android.provider.BlockedNumberContract
。
來(lái)電過(guò)濾
Android 7.0 允許默認(rèn)的手機(jī)應(yīng)用過(guò)濾來(lái)電痛阻。手機(jī)應(yīng)用執(zhí)行此操作的方式是實(shí)現(xiàn)新的 CallScreeningService
菌瘪,該方法允許手機(jī)應(yīng)用基于來(lái)電的 [Call.Details](https://developer.android.com/reference/android/telecom/Call.Details)
執(zhí)行大量操作,例如:
- 拒絕來(lái)電
- 不允許來(lái)電到達(dá)通話記錄
- 不向用戶顯示來(lái)電通知
如需了解詳細(xì)信息阱当,請(qǐng)參閱可下載的 API 參考中的 android.telecom.CallScreeningService
俏扩。
多語(yǔ)言區(qū)域支持,更多語(yǔ)言
Android 7.0 現(xiàn)在允許用戶在設(shè)置中選擇多個(gè)語(yǔ)言區(qū)域弊添,以更好地支持雙語(yǔ)用例录淡。應(yīng)用可以使用新的 API 獲取用戶選擇的語(yǔ)言區(qū)域,然后為多區(qū)域設(shè)置用戶提供更成熟的用戶體驗(yàn) — 如以多個(gè)語(yǔ)言顯示搜索結(jié)果油坝,并且不會(huì)以用戶了解的語(yǔ)言翻譯網(wǎng)頁(yè)嫉戚。
除多語(yǔ)言區(qū)域支持外,Android 7.0 還擴(kuò)展了用戶可用的語(yǔ)言范圍澈圈。它針對(duì)常用語(yǔ)言提供超過(guò) 25 種的變體彬檀,如英語(yǔ)、西班牙語(yǔ)瞬女、法語(yǔ)和阿拉伯語(yǔ)窍帝。它還針對(duì) 100 多種新語(yǔ)言添加了部分支持。
應(yīng)用可以通過(guò)調(diào)用 LocaleList.GetDefault()
獲取用戶設(shè)置的語(yǔ)言區(qū)域列表诽偷。為支持?jǐn)U展的語(yǔ)言區(qū)域數(shù)量坤学,Android 7.0 正在改變其解析資源的方式。請(qǐng)務(wù)必使用新的資源解析邏輯測(cè)試和驗(yàn)證您的應(yīng)用是否能如期運(yùn)行报慕。
要了解新資源解析行為和應(yīng)遵循的最佳做法深浮,請(qǐng)參閱多語(yǔ)言支持。
新增的表情符號(hào)
Android 7.0 引入更多表情符號(hào)和表情符號(hào)相關(guān)功能眠冈,包括膚色表情符號(hào)和支持變量選擇符飞苇。如果您的應(yīng)用支持表情符號(hào),請(qǐng)遵循以下準(zhǔn)則蜗顽,以便能充分利用這些表情符號(hào)相關(guān)功能優(yōu)勢(shì)布卡。
-
在插入之前,檢查設(shè)備是否包含表情符號(hào)诫舅。要檢查系統(tǒng)字體中有哪些表情符號(hào)羽利,使用
[hasGlyph(String)](https://developer.android.com/reference/android/graphics/Paint#hasGlyph(java.lang.String))
方法。 - 檢查表情符號(hào)是否支持變量選擇符刊懈。變量選擇符使您能夠呈現(xiàn)一些彩色或黑白的表情符號(hào)这弧。在移動(dòng)設(shè)備上娃闲,應(yīng)用應(yīng)呈現(xiàn)彩色的表情符號(hào),而不是黑白的匾浪。但是皇帮,如果您的應(yīng)用顯示嵌入在文本中的表情符號(hào),那應(yīng)使用黑白變量蛋辈。要確定表情符號(hào)是否有變量属拾,使用變量選擇符。如需有關(guān)支持變量的字符的完整清單冷溶,請(qǐng)參閱變量的 Unicode 文檔中的表情符號(hào)變量序列部分渐白。
-
檢查表情符號(hào)是否支持膚色。Android 7.0 允許用戶按照他們的喜好修改表情符號(hào)呈現(xiàn)的膚色逞频。鍵盤(pán)應(yīng)用應(yīng)為有多個(gè)膚色的表情符號(hào)提供可視化的指示纯衍,并應(yīng)允許用戶選擇他們喜歡的膚色。要確定哪些系統(tǒng)表情符號(hào)有膚色修改器苗胀,使用
[hasGlyph(String)](https://developer.android.com/reference/android/graphics/Paint#hasGlyph(java.lang.String))
方法襟诸。您可以通過(guò)讀取 Unicode 文檔來(lái)確定哪些表情符號(hào)使用膚色。
Android 中的 ICU4J API
Android 7.0 目前在 Android 框架(位于 android.icu
軟件包下)中提供 ICU4J API 的子集基协。遷移很簡(jiǎn)單歌亲,主要是需要從 com.java.icu
命名空間更改為 android.icu
。如果您已在您的應(yīng)用中使用 ICU4J 捆綁包澜驮,切換到 Android 框架中提供的 android.icu
API 可以大量節(jié)省 APK 大小陷揪。
要詳細(xì)了解 Android ICU4J API,請(qǐng)參閱 ICU4J 支持泉唁。
WebView
Chrome 和 WebView 配合使用
從 Android 7.0 及更高版本中的 Chrome 版本 51 開(kāi)始鹅龄,您的設(shè)備中的 Chrome APK 用于提供和渲染 Android 系統(tǒng) WebView揩慕。這種方法改善了設(shè)備本身的內(nèi)存使用率亭畜,同時(shí)減少保持 WebView 更新所需的帶寬(因?yàn)橹灰3謫⒂?Chrome,單機(jī)版 WebView APK 將不再進(jìn)行更新)迎卤。
您可以啟用開(kāi)發(fā)者選項(xiàng)和選擇 WebView 實(shí)現(xiàn)拴鸵,選擇您的 WebView 提供商。您可以使用設(shè)備上安裝的任何兼容的 Chrome 版本(Dev蜗搔、Beta 或 Stable)或單機(jī)版 Webview APK劲藐,作為 WebView 實(shí)現(xiàn)。
多進(jìn)程
從 Android 7.0 中的 Chrome 版本 51 開(kāi)始樟凄,WebView 將開(kāi)發(fā)者選項(xiàng)“多進(jìn)程 WebView”被啟用時(shí)聘芜,在一個(gè)單獨(dú)的沙盒進(jìn)程中運(yùn)行網(wǎng)頁(yè)內(nèi)容。
我們正在尋求關(guān)于 N 中的兼容性和運(yùn)行時(shí)性能的反饋缝龄,并隨后將在未來(lái) Android 版本中啟用多進(jìn)程 WebView汰现。在這個(gè)版本中挂谍,可預(yù)期啟動(dòng)時(shí)間回歸、總內(nèi)存使用和軟件渲染性能瞎饲。
如果您在多進(jìn)程模式中遇到意外問(wèn)題口叙,請(qǐng)告訴我們。請(qǐng)通過(guò) Chromium 錯(cuò)誤跟蹤程序聯(lián)系 WebView 團(tuán)隊(duì)嗅战。
Javascript 在頁(yè)面加載之前運(yùn)行
從以 Android 7.0 為目標(biāo)平臺(tái)的應(yīng)用開(kāi)始妄田,JavaScript 上下文會(huì)在加載新頁(yè)面時(shí)重置。目前驮捍,新 WebView 實(shí)例中加載的第一個(gè)頁(yè)面會(huì)繼承上下文疟呐。
想要在 WebView 中注入 Javascript 的開(kāi)發(fā)者應(yīng)在頁(yè)面開(kāi)始加載后執(zhí)行腳本。
不安全起點(diǎn)上的地理定位
從以 Android 7.0 為目標(biāo)平臺(tái)的應(yīng)用開(kāi)始东且,地理定位 API 將僅在安全的起點(diǎn)(通過(guò) HTTPS)上被允許萨醒。此政策的目的是在用戶使用不安全連接時(shí)保護(hù)他們的私人信息。
測(cè)試 WebView 測(cè)試版
WebViewis 定期更新苇倡,因此我們建議您經(jīng)常使用 WebView 的測(cè)試版本測(cè)試應(yīng)用的兼容性富纸。要在 Android 7.0 上著手測(cè)試 WebView 的預(yù)發(fā)布版本,請(qǐng)下載并安裝 Chrome Dev 或 Chrome 測(cè)試版旨椒,然后按上述說(shuō)明在開(kāi)發(fā)者選項(xiàng)下面選擇它作為 WebView 實(shí)現(xiàn)晓褪。請(qǐng)通過(guò) Chromium 錯(cuò)誤跟蹤程序報(bào)告問(wèn)題,以便我們可以在發(fā)布新的 WebView 版本前修復(fù)問(wèn)題综慎。
OpenGL? ES 3.2 API
Android 7.0 添加了框架接口和對(duì) OpenGL ES 3.2 的平臺(tái)支持涣仿,包括:
- 來(lái)自 Android 擴(kuò)展包 (AEP) 的所有擴(kuò)展(
EXT_texture_sRGB_decode
除外)。 - 針對(duì) HDR 的浮點(diǎn)幀緩沖和延遲著色示惊。
- BaseVertex 繪圖調(diào)用可實(shí)現(xiàn)更好的批處理和流媒體服務(wù)好港。
- 強(qiáng)大的緩沖區(qū)訪問(wèn)控制可減少 WebGL 開(kāi)銷。
Android 7.0 上適用于 OpenGL ES 3.2 的框架 API 與 GLES32
類一起提供米罚。使用 OpenGL ES 3.2 時(shí)钧汹,請(qǐng)務(wù)必通過(guò) <uses-feature>
標(biāo)記和 android:glEsVersion
屬性在您的清單文件中聲明要求。
如需了解有關(guān)使用 OpenGL ES 的信息录择,包括如何在運(yùn)行時(shí)檢查設(shè)備支持的 OpenGL ES 版本拔莱,請(qǐng)參閱 OpenGL ES API 指南。
Android TV 錄制
Android 7.0 通過(guò)新的錄制 API 添加了從 Android TV 輸入服務(wù)錄制和播放內(nèi)容的功能隘竭。構(gòu)建在現(xiàn)有時(shí)移 API 之上塘秦,TV 輸入服務(wù)可以控制能夠錄制的渠道數(shù)據(jù)、保存錄制的會(huì)話的方式动看,同時(shí)可通過(guò)錄制的內(nèi)容管理用戶交互尊剔。
如需了解詳細(xì)信息,請(qǐng)參閱 Android TV Recording API菱皆。
Android for Work
Android for Work 針對(duì)運(yùn)行 Android 7.0 的設(shè)備添加了許多新功能和 API须误。部分重要內(nèi)容如下— 有關(guān)變更的完整列表笔咽,請(qǐng)參閱 Android for Work 更新。
工作資料安全性挑戰(zhàn)
面向 N SDK 的配置文件所有者可以為在工作資料中運(yùn)行的應(yīng)用指定單獨(dú)的安全性挑戰(zhàn)霹期。當(dāng)用戶嘗試打開(kāi)任何工作應(yīng)用時(shí)將顯示工作挑戰(zhàn)叶组。成功完成安全性挑戰(zhàn)可解鎖工作資料并將其解密(如果需要)。對(duì)于配置文件所有者历造,ACTION_SET_NEW_PASSWORD
提示用戶設(shè)置工作挑戰(zhàn)甩十,ACTION_SET_NEW_PARENT_PROFILE_PASSWORD
提示用戶設(shè)置設(shè)備鎖。
配置文件所有者可以使用 setPasswordQuality()
吭产、setPasswordMinimumLength()
和相關(guān)方法針對(duì)工作挑戰(zhàn)設(shè)置不同的密碼策略(例如侣监,PIN 碼必須多長(zhǎng),或是否可以使用指紋解鎖配置文件)臣淤。配置文件所有者還可以使用新的 getParentProfileInstance()
方法返回的 DevicePolicyManager
實(shí)例設(shè)置設(shè)備鎖定橄霉。此外,配置文件所有者可以使用新的 setOrganizationColor()
和 setOrganizationName()
方法針對(duì)工作挑戰(zhàn)自定義憑據(jù)屏幕邑蒋。
關(guān)閉工作
在有工作資料的設(shè)備上姓蜂,用戶可以切換工作模式。工作模式關(guān)閉時(shí)医吊,管理的用戶臨時(shí)關(guān)閉钱慢,其停用托管工作資料應(yīng)用、后臺(tái)同步和通知卿堂。這包括配置文件所有者應(yīng)用束莫。關(guān)閉工作模式時(shí),系統(tǒng)顯示永久狀態(tài)圖標(biāo)草描,以提醒用戶他們無(wú)法啟動(dòng)工作應(yīng)用览绿。啟動(dòng)器指示該工作應(yīng)用和小部件無(wú)法訪問(wèn)。
Always on VPN
設(shè)備所有者和配置文件所有者可以確保工作應(yīng)用始終通過(guò)指定的 VPN 連接穗慕。系統(tǒng)在設(shè)備啟動(dòng)后自動(dòng)啟動(dòng)該 VPN饿敲。
新的 DevicePolicyManager
方法為 setAlwaysOnVpnPackage()
和 getAlwaysOnVpnPackage()
。
由于 VPN 服務(wù)無(wú)需應(yīng)用交互即可由系統(tǒng)直接綁定揍诽,因此诀蓉,VPN 客戶端必須針對(duì) Always on VPN 處理新的入口點(diǎn)栗竖。和以前一樣暑脆,由與操作 android.net.VpnService
匹配的 intent 過(guò)濾器將服務(wù)指示給系統(tǒng)。
用戶還可以使用 Settings>More>Vpn 手動(dòng)設(shè)置實(shí)現(xiàn) VPNService
方法的 Always on VPN 客戶端狐肢。通過(guò)“設(shè)置”啟用 Always on VPN 的選項(xiàng)僅在 VPN 客戶端以 API 級(jí)別 24 為目標(biāo)時(shí)可用添吗。
自定義配置
應(yīng)用可以用企業(yè)顏色和徽標(biāo)來(lái)自定義配置文件所有者和設(shè)備所有者配置流程。DevicePolicyManager.EXTRA_PROVISIONING_MAIN_COLOR
自定義流程顏色份名。DevicePolicyManager.EXTRA_PROVISIONING_LOGO_URI
用企業(yè)徽標(biāo)自定義流程碟联。
無(wú)障礙增強(qiáng)功能
Android 7.0 現(xiàn)在針對(duì)新的設(shè)備設(shè)置直接在歡迎屏幕上提供“Vision Settings”妓美。這使用戶可以更容易發(fā)現(xiàn)和配置他們?cè)O(shè)備上的無(wú)障礙功能,包括放大手勢(shì)鲤孵、字體大小壶栋、顯示屏尺寸和話語(yǔ)提示。
隨著這些無(wú)障礙功能更為突出普监,在啟用這些功能后贵试,您的用戶更可能試用您的應(yīng)用。請(qǐng)務(wù)必提前啟用這些設(shè)置測(cè)試您的應(yīng)用凯正。您可以通過(guò) Settings > Accessibility 啟用它們毙玻。
還是在 Android 7.0 中,無(wú)障礙服務(wù)現(xiàn)在可以幫助具有動(dòng)作障礙的用戶觸摸屏幕廊散。全新的 API 允許使用人臉追蹤桑滩、眼球追蹤、點(diǎn)掃描等功能構(gòu)建服務(wù)允睹,以滿足這些用戶的需求运准。
如需了解詳細(xì)信息,請(qǐng)參閱可下載的 API 參考中的 android.accessibilityservice.GestureDescription
缭受。
直接啟動(dòng)
直接啟動(dòng)可以縮短設(shè)備啟動(dòng)時(shí)間戳吝,讓注冊(cè)的應(yīng)用具有有限的功能,即使在意外重啟后贯涎。例如听哭,如果當(dāng)用戶睡覺(jué)時(shí)加密的設(shè)備重啟,那么注冊(cè)的警報(bào)塘雳、消息和來(lái)電現(xiàn)在可以和往常一樣繼續(xù)通知用戶陆盘。這也意味著重啟后無(wú)障礙服務(wù)會(huì)立即可用。
在 Android 7.0 中败明,直接啟動(dòng)充分利用基于文件的加密隘马,以針對(duì)系統(tǒng)和應(yīng)用數(shù)據(jù)啟用細(xì)化的加密策略。系統(tǒng)針對(duì)選定的系統(tǒng)數(shù)據(jù)和顯式注冊(cè)的應(yīng)用數(shù)據(jù)使用設(shè)備加密存儲(chǔ)妻顶。默認(rèn)情況下酸员,憑據(jù)加密存儲(chǔ)可用于所有其他系統(tǒng)數(shù)據(jù)、用戶數(shù)據(jù)讳嘱、應(yīng)用及應(yīng)用數(shù)據(jù)幔嗦。
啟動(dòng)時(shí),系統(tǒng)在受限的模式中啟動(dòng)沥潭,僅訪問(wèn)設(shè)備加密數(shù)據(jù)邀泉,不會(huì)對(duì)應(yīng)用或數(shù)據(jù)進(jìn)行常規(guī)訪問(wèn)。如果您有想要在此模式下運(yùn)行的組件,您可以通過(guò)在清單中設(shè)置標(biāo)記注冊(cè)它們汇恤。重啟后庞钢,系統(tǒng)通過(guò)廣播 LOCKED_BOOT_COMPLETED
intent 激活注冊(cè)的組件。系統(tǒng)確保注冊(cè)的設(shè)備加密的應(yīng)用數(shù)據(jù)在解鎖前可用因谎。所有其他數(shù)據(jù)在用戶確認(rèn)鎖定屏幕憑據(jù)進(jìn)行解密前均不可用基括。
如需了解詳細(xì)信息,請(qǐng)參閱直接啟動(dòng)财岔。
密鑰認(rèn)證
Android 7.0 引入密鑰認(rèn)證阱穗,這是一個(gè)新的安全工具,可幫助您確保設(shè)備的硬件支持的密鑰庫(kù)中存儲(chǔ)的密鑰對(duì)適當(dāng)保護(hù)您的應(yīng)用使用的敏感信息使鹅。借助此工具揪阶,您可以更加放心地讓您的應(yīng)用與駐留在安全硬件中的密鑰交互,即使運(yùn)行您的應(yīng)用的設(shè)備已被破解 root 權(quán)限患朱。如果您在應(yīng)用中使用硬件支持的密鑰庫(kù)中的密鑰鲁僚,您應(yīng)使用此工具,尤其當(dāng)您使用密鑰驗(yàn)證應(yīng)用中的敏感信息時(shí)裁厅。
通過(guò)密鑰認(rèn)證冰沙,您可以在設(shè)備的可信執(zhí)行環(huán)境 (TEE) 中驗(yàn)證在設(shè)備的硬件支持的密鑰庫(kù)中創(chuàng)建和存儲(chǔ)的 RSA 或 EC 密鑰對(duì)。通過(guò)此工具执虹,您還可以使用設(shè)備服務(wù)拓挥,例如您的應(yīng)用的后端服務(wù)器,確定和有效驗(yàn)證密鑰對(duì)的使用和有效性袋励。這些功能為保護(hù)密鑰對(duì)提供額外的安全級(jí)別侥啤,即使有人破解設(shè)備的 root 權(quán)限或損害運(yùn)行于設(shè)備的 Android 平臺(tái)的安全。
注:僅少部分運(yùn)行 Android 7.0 的設(shè)備支持硬件級(jí)密鑰認(rèn)證茬故;其他所有運(yùn)行 Android 7.0 的設(shè)備則使用軟件級(jí)密鑰認(rèn)證盖灸。在生產(chǎn)級(jí)環(huán)境中驗(yàn)證設(shè)備的硬件支持的密鑰之屬性前,您應(yīng)確保設(shè)備支持硬件級(jí)密鑰認(rèn)證磺芭。為此赁炎,您應(yīng)確保認(rèn)證證書(shū)鏈包含由 Google 認(rèn)證根密鑰簽署的根證書(shū),且密鑰說(shuō)明數(shù)據(jù)結(jié)構(gòu)中的 attestationSecurityLevel
元素設(shè)置為 TrustedEnvironment 安全級(jí)別钾腺。
如需了解詳細(xì)信息徙垫,請(qǐng)參閱密鑰認(rèn)證開(kāi)發(fā)者文檔。
網(wǎng)絡(luò)安全性配置
在 Android 7.0 中放棒,通過(guò)使用說(shuō)明性“網(wǎng)絡(luò)安全性配置”(而不是使用傳統(tǒng)的易出錯(cuò)的編程 API(例如姻报,X509TrustManager)),應(yīng)用可以安全地自定義其安全(HTTPS哨查、TLS)連接的行為逗抑,無(wú)需任何代碼修改。
支持的功能:
- 自定義信任錨寒亥。讓?xiě)?yīng)用可以針對(duì)安全連接自定義哪些證書(shū)頒發(fā)機(jī)構(gòu) (CA) 值得信賴邮府。例如,信任特定的自簽署證書(shū)或限制應(yīng)用信任的公共 CA 集溉奕。
- 僅調(diào)試重寫(xiě)褂傀。讓?xiě)?yīng)用開(kāi)發(fā)者可以安全調(diào)試其應(yīng)用的安全連接,而不會(huì)增加安裝基礎(chǔ)的風(fēng)險(xiǎn)加勤。
- 明文流量選擇退出仙辟。讓?xiě)?yīng)用可以防止自身意外使用明文流量。
- 證書(shū)固定鳄梅。這是一項(xiàng)高級(jí)功能叠国,讓?xiě)?yīng)用可以針對(duì)安全連接限制哪些服務(wù)器密鑰受信任。
如需了解詳細(xì)信息戴尸,請(qǐng)參閱網(wǎng)絡(luò)安全性配置粟焊。
默認(rèn)受信任的證書(shū)頒發(fā)機(jī)構(gòu)
默認(rèn)情況下,面向 Android 7.0 的應(yīng)用僅信任系統(tǒng)提供的證書(shū)孙蒙,且不再信任用戶添加的證書(shū)頒發(fā)機(jī)構(gòu) (CA)项棠。如果面向 Android N 的應(yīng)用希望信任用戶添加的 CA,則應(yīng)使用網(wǎng)絡(luò)安全性配置以指定信任用戶 CA 的方式挎峦。
APK signature scheme v2
Android 7.0 引入一項(xiàng)新的應(yīng)用簽名方案 APK Signature Scheme v2香追,它能提供更快的應(yīng)用安裝時(shí)間和更多針對(duì)未授權(quán) APK 文件更改的保護(hù)。在默認(rèn)情況下坦胶,Android Studio 2.2 和 Android Plugin for Gradle 2.2 會(huì)使用 APK Signature Scheme v2 和傳統(tǒng)簽名方案來(lái)簽署您的應(yīng)用透典。
雖然我們建議您對(duì)您的應(yīng)用采用 APK Signature Scheme v2,但這項(xiàng)新方案并非強(qiáng)制性的顿苇。如果您的應(yīng)用在使用 APK Signature Scheme v2 時(shí)不能正確開(kāi)發(fā)掷匠,您可以停用這項(xiàng)新方案。禁用過(guò)程會(huì)導(dǎo)致 Android Studio 2.2 和 Android Plugin for Gradle 2.2 僅使用傳統(tǒng)簽名方案來(lái)簽署您的應(yīng)用岖圈。要僅用傳統(tǒng)方案簽署讹语,打開(kāi)模塊級(jí) build.gradle
文件,然后將行 v2SigningEnabled false
添加到您的版本簽名配置中:
android {
...
defaultConfig { ... }
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
v2SigningEnabled false
}
}
}
注意:如果您使用 APK Signature Scheme v2 簽署您的應(yīng)用蜂科,并對(duì)應(yīng)用進(jìn)行了進(jìn)一步更改顽决,則應(yīng)用的簽名將無(wú)效。出于這個(gè)原因导匣,請(qǐng)?jiān)谑褂?APK Signature Scheme v2 簽署您的應(yīng)用之前才菠、而非之后使用 zipalign
等工具。
如需了解詳細(xì)信息贡定,請(qǐng)閱讀相關(guān)的 Android Studio 文檔赋访,這些文檔介紹了如何在 Android Studio 中簽署應(yīng)用以及如何使用 Android Plugin for Gradle 為簽署應(yīng)用配置構(gòu)建文件。
作用域目錄訪問(wèn)
在 Android 7.0 中,應(yīng)用可以使用新的 API 請(qǐng)求訪問(wèn)特定的外部存儲(chǔ)目錄蚓耽,包括可移動(dòng)媒體上的目錄渠牲,如 SD 卡。新 API 大大簡(jiǎn)化了應(yīng)用訪問(wèn)標(biāo)準(zhǔn)外部存儲(chǔ)目錄的方式步悠,如 Pictures
目錄签杈。應(yīng)用(如照片應(yīng)用)可以使用這些 API(而不是使用 READ_EXTERNAL_STORAGE
),其授予所有存儲(chǔ)目錄的訪問(wèn)權(quán)限或存儲(chǔ)訪問(wèn)框架鼎兽,從而讓用戶可以導(dǎo)航到目錄答姥。
此外,新的 API 簡(jiǎn)化了用戶向應(yīng)用授予外部存儲(chǔ)訪問(wèn)權(quán)限的步驟谚咬。當(dāng)您使用新的 API 時(shí)鹦付,系統(tǒng)使用一個(gè)簡(jiǎn)單的權(quán)限 UI,其清楚地詳細(xì)介紹應(yīng)用正在請(qǐng)求訪問(wèn)的目錄择卦。
如需了解詳細(xì)信息敲长,請(qǐng)參閱作用域目錄訪問(wèn)開(kāi)發(fā)者文檔。
鍵盤(pán)快捷鍵輔助工具
在 Android 7.0 中互捌,用戶可以按“Meta + /”觸發(fā)“鍵盤(pán)快捷鍵”屏幕潘明,它會(huì)顯示的系統(tǒng)和對(duì)焦的應(yīng)用中可用的所有快捷鍵。如果快捷鍵存在秕噪,系統(tǒng)自動(dòng)從應(yīng)用菜單檢索這些快捷鍵钳降。您也可以為屏幕提供微調(diào)的快捷鍵列表。您可以通過(guò)重寫(xiě)新 Activity.onProvideKeyboardShortcuts()
的方法來(lái)進(jìn)行這項(xiàng)操作腌巾,如可下載的 API 參考中所述遂填。
注:所有鍵盤(pán)都沒(méi)有 Meta 鍵:在 Macintosh 鍵盤(pán)上,它是 Command 鍵澈蝙;在 Windows 鍵盤(pán)上吓坚,它是 Windows 鍵;而在 Pixel C 和 Chrome 操作系統(tǒng)鍵盤(pán)上灯荧,它是 Search 鍵礁击。
要在您的應(yīng)用的任何地方觸發(fā)鍵盤(pán)快捷鍵輔助工具,為相關(guān) Activity 調(diào)用 Activity.requestKeyboardShortcutsHelper()
逗载。
Custom Pointer API
Android 7.0 引入 Custom Pointer API哆窿,以便您可以自定義指針的外觀、 可見(jiàn)性和行為厉斟。此功能在用戶使用鼠標(biāo)或觸控板與 UI 對(duì)象交互尤為有用挚躯。默認(rèn)指針使用標(biāo)準(zhǔn)圖標(biāo)。此 API 還包含多種高級(jí)功能擦秽,例如根據(jù)鼠標(biāo)或觸控板特定移動(dòng)情況改變指針圖標(biāo)外觀码荔。
要設(shè)置指針圖標(biāo)漩勤,請(qǐng)?zhí)鎿Q View
類的 onResolvePointerIcon()
方法。此方法使用 PointerIcon
對(duì)象繪制與特定移動(dòng)事件對(duì)應(yīng)的圖標(biāo)缩搅。
Sustained Performance API
長(zhǎng)期運(yùn)行的應(yīng)用的性能可能會(huì)顯著波動(dòng)越败,因?yàn)橄到y(tǒng)會(huì)阻止系統(tǒng)芯片在設(shè)備組件達(dá)到溫度限制時(shí)啟動(dòng)。這種波動(dòng)是建立高性能長(zhǎng)期運(yùn)行應(yīng)用的應(yīng)用開(kāi)發(fā)者的移動(dòng)目標(biāo)誉己。
為解決這些限制眉尸,Android 7.0 包括了對(duì)持續(xù)性能模式的支持域蜗,幫助原始設(shè)備制造商 (OEM) 提供關(guān)于長(zhǎng)期運(yùn)行應(yīng)用的設(shè)備性能能力的提示巨双。應(yīng)用開(kāi)發(fā)者可以使用這些提示來(lái)根據(jù)可預(yù)測(cè)的一致設(shè)備性能水平調(diào)整長(zhǎng)期應(yīng)用。
應(yīng)用開(kāi)發(fā)者只能在 Nexus 6P 設(shè)備的 Android 7.0 中嘗試這款新 API霉祸。要使用此功能筑累,為您希望以持續(xù)性能模式運(yùn)行的窗口設(shè)置持續(xù)性能窗口標(biāo)記。使用 Window.setSustainedPerformanceMode()
方法設(shè)置此標(biāo)記丝蹭。當(dāng)窗口不再對(duì)焦時(shí)慢宗,系統(tǒng)會(huì)自動(dòng)停用此模式。
VR 支持
Android 7.0 添加了新的 VR 模式的平臺(tái)支持和優(yōu)化奔穿,以使開(kāi)發(fā)者能為用戶打造高質(zhì)量移動(dòng) VR 體驗(yàn)镜沽。增加了一些性能增強(qiáng)特性,包括允許 VR 應(yīng)用訪問(wèn)某個(gè)專屬的 CPU 核心贱田。在您的應(yīng)用中缅茉,您可以充分利用到專為 VR 設(shè)計(jì)的智能頭部跟蹤和立體聲通知功能。最重要的是男摧,Android 7.0 的圖形延時(shí)非常低蔬墩。如需了解有關(guān)開(kāi)發(fā)面向 Android 7.0 的 VR 應(yīng)用的完整信息,請(qǐng)參閱面向 Android 的 Google VR SDK耗拓。
打印服務(wù)增強(qiáng)
在 Android 7.0 中拇颅,打印服務(wù)開(kāi)發(fā)者現(xiàn)在可以公開(kāi)關(guān)于個(gè)別打印機(jī)和打印作業(yè)的其他信息。
在列出各打印機(jī)時(shí)乔询,打印服務(wù)現(xiàn)在可以通過(guò)兩種方式來(lái)設(shè)置按打印機(jī)的圖標(biāo):
- 您可以通過(guò)調(diào)用
PrinterInfo.Builder.setResourceIconId()
設(shè)置源于資源 ID 的圖標(biāo) - 您可以通過(guò)調(diào)用
PrinterInfo.Builder.setHasCustomPrinterIcon()
樟插,并針對(duì)使用android.printservice.PrinterDiscoverySession.onRequestCustomPrinterIcon()
請(qǐng)求圖標(biāo)的情況設(shè)置回調(diào)來(lái)顯示源自網(wǎng)絡(luò)的圖標(biāo)
此外,您還可以通過(guò)調(diào)用 PrinterInfo.Builder.setInfoIntent()
提供按打印機(jī)活動(dòng)竿刁,以顯示其他信息乒验。
您可以通過(guò)分別調(diào)用 android.printservice.PrintJob.setProgress()
和 android.printservice.PrintJob.setStatus()
在打印任務(wù)通知中指示打印任務(wù)的進(jìn)度和狀態(tài)。
如需了解有關(guān)這些方法的詳細(xì)信息赌渣,請(qǐng)參閱可下載的 API 參考郎笆。
FrameMetricsListener API
FrameMetricsListener API 允許應(yīng)用監(jiān)測(cè)它的 UI 渲染性能。API 通過(guò)公開(kāi)流式傳輸 Pub/Sub API 來(lái)提供此能力监婶,以傳遞應(yīng)用當(dāng)前窗口的幀計(jì)時(shí)信息旅赢。返回的數(shù)據(jù)相當(dāng)于 [adb shell](https://developer.android.com/tools/help/shell#shellcommands) dumpsys gfxinfo framestats
顯示的數(shù)據(jù)齿桃,但不限定于在過(guò)去的 120 幀內(nèi)。
您可以使用 FrameMetricsListener 來(lái)衡量生產(chǎn)中的交互級(jí) UI 性能煮盼,無(wú)需 USB 連接短纵。此 API 允許在比 adb shell dumpsys gfxinfo
更高的粒度上收集數(shù)據(jù)。因?yàn)橄到y(tǒng)可以從應(yīng)用中的特定交互中收集數(shù)據(jù)僵控,因此更高的粒度變得可行香到;系統(tǒng)不需要采集關(guān)于完整應(yīng)用性能的全局概要或清除任何全局狀態(tài)。您可以使用這種能力來(lái)針對(duì)應(yīng)用的真實(shí)使用案例收集性能數(shù)據(jù)和捕捉 UI 性能回歸报破。
要監(jiān)測(cè)一個(gè)窗口悠就,實(shí)現(xiàn) FrameMetricsListener.onMetricsAvailable()
回調(diào)方法,并在窗口上注冊(cè)充易。如需了解詳細(xì)信息梗脾,請(qǐng)參閱可下載的 API 參考中的 FrameMetricsListener
類文檔。
API 提供了一個(gè)包含計(jì)時(shí)數(shù)據(jù)的 FrameMetrics
對(duì)象盹靴,其渲染子系統(tǒng)會(huì)在一幀長(zhǎng)度內(nèi)報(bào)告各種里程碑炸茧。支持的指標(biāo)有:UNKNOWN_DELAY_DURATION
、INPUT_HANDLING_DURATION
稿静、ANIMATION_DURATION
梭冠、LAYOUT_MEASURE_DURATION
、DRAW_DURATION
改备、 SYNC_DURATION
控漠、COMMAND_ISSUE_DURATION
、SWAP_BUFFERS_DURATION
绍妨、TOTAL_DURATION
和 FIRST_DRAW_FRAME
润脸。
虛擬文件
在較早的 Android 版本中,您的應(yīng)用可以使用存儲(chǔ)訪問(wèn)框架來(lái)允許用戶從他們的云存儲(chǔ)帳戶中選擇文件他去,如 Google Drive毙驯。但是,不能表示沒(méi)有直接字節(jié)碼表示的文件灾测;每個(gè)文件都必須提供一個(gè)輸入流爆价。
Android 7.0 在存儲(chǔ)訪問(wèn)框架中添加了虛擬文件的概念。虛擬文件功能可以讓您的 [DocumentsProvider](https://developer.android.com/reference/android/provider/DocumentsProvider)
返回可與 [ACTION_VIEW](https://developer.android.com/reference/android/content/Intent#ACTION_VIEW)
intent 使用的文件 URI媳搪,即使它們沒(méi)有直接字節(jié)碼表示铭段。Android 7.0 還允許您為用戶文件(虛擬或其他類)提供備用格式。
為獲得您的應(yīng)用中的虛擬文件的 URI秦爆,首先您應(yīng)創(chuàng)建一個(gè) [Intent](https://developer.android.com/reference/android/content/Intent)
以打開(kāi)文件選擇器 UI序愚。由于應(yīng)用不能使用 [openInputStream()](https://developer.android.com/reference/android/content/ContentResolver#openInputStream(android.net.Uri))
方法來(lái)直接打開(kāi)一個(gè)虛擬文件,因此如果您包括了 [CATEGORY_OPENABLE](https://developer.android.com/reference/android/content/Intent#CATEGORY_OPENABLE)
類別等限,您的應(yīng)用不會(huì)收到任何虛擬文件爸吮。
在用戶選擇之后芬膝,系統(tǒng)調(diào)用 [onActivityResult()](https://developer.android.com/reference/android/app/Activity#onActivityResult(int,%20int,%20android.content.Intent))
方法。您的應(yīng)用可以檢索虛擬文件的 URI形娇,并得到一個(gè)輸入流锰霜,這表現(xiàn)在以下片段中的代碼。
// Other Activity code ...
final static private int REQUEST_CODE = 64;
// We listen to the OnActivityResult event to respond to the user's selection.
@Override
public void onActivityResult(int requestCode, int resultCode,
Intent resultData) {
try {
if (requestCode == REQUEST_CODE &&
resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
ContentResolver resolver = getContentResolver();
// Before attempting to coerce a file into a MIME type,
// check to see what alternative MIME types are available to
// coerce this file into.
String[] streamTypes =
resolver.getStreamTypes(uri, "*/*");
AssetFileDescriptor descriptor =
resolver.openTypedAssetFileDescriptor(
uri,
streamTypes[0],
null);
// Retrieve a stream to the virtual file.
InputStream inputStream = descriptor.createInputStream();
}
}
} catch (Exception ex) {
Log.e("EXCEPTION", "ERROR: ", ex);
}
}
如需了解有關(guān)訪問(wèn)用戶文件的詳細(xì)信息桐早,請(qǐng)參閱存儲(chǔ)訪問(wèn)框架指南癣缅。
電池和內(nèi)存
Android 7.0 包括旨在延長(zhǎng)設(shè)備電池壽命和減少 RAM 使用的系統(tǒng)行為變更。這些變更可能會(huì)影響您的應(yīng)用訪問(wèn)系統(tǒng)資源哄酝,以及您的應(yīng)用通過(guò)特定隱式 intent 與其他應(yīng)用交互的方式友存。
低電耗模式
Android 6.0(API 級(jí)別 23)引入了低電耗模式,當(dāng)用戶設(shè)備未插接電源炫七、處于靜止?fàn)顟B(tài)且屏幕關(guān)閉時(shí)爬立,該模式會(huì)推遲 CPU 和網(wǎng)絡(luò)活動(dòng)钾唬,從而延長(zhǎng)電池壽命万哪。而 Android 7.0 則通過(guò)在設(shè)備未插接電源且屏幕關(guān)閉狀態(tài)下、但不一定要處于靜止?fàn)顟B(tài)(例如用戶外出時(shí)把手持式設(shè)備裝在口袋里)時(shí)應(yīng)用部分 CPU 和網(wǎng)絡(luò)限制抡秆,進(jìn)一步增強(qiáng)了低電耗模式奕巍。
當(dāng)設(shè)備處于充電狀態(tài)且屏幕已關(guān)閉一定時(shí)間后,設(shè)備會(huì)進(jìn)入低電耗模式并應(yīng)用第一部分限制:關(guān)閉應(yīng)用網(wǎng)絡(luò)訪問(wèn)儒士、推遲作業(yè)和同步的止。如果進(jìn)入低電耗模式后設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間,系統(tǒng)則會(huì)對(duì) [PowerManager.WakeLock](https://developer.android.com/reference/android/os/PowerManager.WakeLock)
着撩、[AlarmManager](https://developer.android.com/reference/android/app/AlarmManager)
鬧鈴诅福、GPS 和 WLAN 掃描應(yīng)用余下的低電耗模式限制。無(wú)論是應(yīng)用部分還是全部低電耗模式限制拖叙,系統(tǒng)都會(huì)喚醒設(shè)備以提供簡(jiǎn)短的維護(hù)時(shí)間窗口氓润,在此窗口期間,應(yīng)用程序可以訪問(wèn)網(wǎng)絡(luò)并執(zhí)行任何被推遲的作業(yè)/同步薯鳍。
[圖片上傳失敗...(image-d92485-1590040583767)]
低電耗模式如何在設(shè)備處于靜止?fàn)顟B(tài)達(dá)到一定時(shí)間后應(yīng)用第二級(jí)系統(tǒng)活動(dòng)限制咖气。
請(qǐng)注意,激活屏幕或插接設(shè)備電源時(shí)挖滤,系統(tǒng)將退出低電耗模式并移除這些處理限制崩溪。此項(xiàng)新增的行為不會(huì)影響有關(guān)使您的應(yīng)用適應(yīng) Android 6.0(API 級(jí)別 23)中所推出的舊版本低電耗模式的建議和最佳做法,如對(duì)低電耗模式和應(yīng)用待機(jī)模式進(jìn)行針對(duì)性優(yōu)化中所討論斩松。您仍應(yīng)遵循這些建議(例如使用 Google 云消息傳遞 (GCM) 發(fā)送和接收消息)并開(kāi)始安排更新計(jì)劃以適應(yīng)新增的低電耗模式行為伶唯。
Project Svelte:后臺(tái)優(yōu)化
Android 7.0 移除了三項(xiàng)隱式廣播,以幫助優(yōu)化內(nèi)存使用和電量消耗惧盹。此項(xiàng)變更很有必要乳幸,因?yàn)殡[式廣播會(huì)在后臺(tái)頻繁啟動(dòng)已注冊(cè)偵聽(tīng)這些廣播的應(yīng)用奋救。刪除這些廣播可以顯著提升設(shè)備性能和用戶體驗(yàn)。
移動(dòng)設(shè)備會(huì)經(jīng)歷頻繁的連接變更反惕,例如在 WLAN 和移動(dòng)數(shù)據(jù)之間切換時(shí)尝艘。目前,可以通過(guò)在應(yīng)用清單中注冊(cè)一個(gè)接收器來(lái)偵聽(tīng)隱式 [CONNECTIVITY_ACTION](https://developer.android.com/reference/android/net/ConnectivityManager#CONNECTIVITY_ACTION)
廣播姿染,讓?xiě)?yīng)用能夠監(jiān)控這些變更背亥。由于很多應(yīng)用會(huì)注冊(cè)接收此廣播,因此單次網(wǎng)絡(luò)切換即會(huì)導(dǎo)致所有應(yīng)用被喚醒并同時(shí)處理此廣播悬赏。
同理狡汉,在之前版本的 Android 中,應(yīng)用可以注冊(cè)接收來(lái)自其他應(yīng)用(例如相機(jī))的隱式 [ACTION_NEW_PICTURE](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_PICTURE)
和 [ACTION_NEW_VIDEO](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_VIDEO)
廣播闽颇。當(dāng)用戶使用相機(jī)應(yīng)用拍攝照片時(shí)盾戴,這些應(yīng)用即會(huì)被喚醒以處理廣播。
為緩解這些問(wèn)題兵多,Android 7.0 應(yīng)用了以下優(yōu)化措施:
- 面向 Android 7.0 開(kāi)發(fā)的應(yīng)用不會(huì)收到
[CONNECTIVITY_ACTION](https://developer.android.com/reference/android/net/ConnectivityManager#CONNECTIVITY_ACTION)
廣播尖啡,即使它們已有清單條目來(lái)請(qǐng)求接受這些事件的通知。在前臺(tái)運(yùn)行的應(yīng)用如果使用[BroadcastReceiver](https://developer.android.com/reference/android/content/BroadcastReceiver)
請(qǐng)求接收通知剩膘,則仍可以在主線程中偵聽(tīng)CONNECTIVITY_CHANGE
衅斩。 - 應(yīng)用無(wú)法發(fā)送或接收
[ACTION_NEW_PICTURE](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_PICTURE)
或[ACTION_NEW_VIDEO](https://developer.android.com/reference/android/hardware/Camera#ACTION_NEW_VIDEO)
廣播。此項(xiàng)優(yōu)化會(huì)影響所有應(yīng)用怠褐,而不僅僅是面向 Android 7.0 的應(yīng)用畏梆。
如果您的應(yīng)用使用任何 intent,您仍需要盡快移除它們的依賴關(guān)系奈懒,以正確適配 Android 7.0 設(shè)備奠涌。Android 框架提供多個(gè)解決方案來(lái)緩解對(duì)這些隱式廣播的需求。例如磷杏,[JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler)
API 提供了一個(gè)穩(wěn)健可靠的機(jī)制來(lái)安排滿足指定條件(例如連入無(wú)限流量網(wǎng)絡(luò))時(shí)所執(zhí)行的網(wǎng)絡(luò)操作溜畅。您甚至可以使用 [JobScheduler](https://developer.android.com/reference/android/app/job/JobScheduler)
來(lái)適應(yīng)內(nèi)容提供程序變化。
如需了解有關(guān) Android N 中后臺(tái)優(yōu)化以及如何改寫(xiě)應(yīng)用的詳細(xì)信息茴丰,請(qǐng)參閱后臺(tái)優(yōu)化达皿。
權(quán)限更改
Android 7.0 做了一些權(quán)限更改,這些更改可能會(huì)影響您的應(yīng)用贿肩。
系統(tǒng)權(quán)限更改
為了提高私有文件的安全性峦椰,面向 Android 7.0 或更高版本的應(yīng)用私有目錄被限制訪問(wèn) (0700
)。此設(shè)置可防止私有文件的元數(shù)據(jù)泄漏汰规,如它們的大小或存在性汤功。此權(quán)限更改有多重副作用:
-
私有文件的文件權(quán)限不應(yīng)再由所有者放寬,為使用
[MODE_WORLD_READABLE](https://developer.android.com/reference/android/content/Context#MODE_WORLD_READABLE)
和/或[MODE_WORLD_WRITEABLE](https://developer.android.com/reference/android/content/Context#MODE_WORLD_WRITEABLE)
而進(jìn)行的此類嘗試將觸發(fā)[SecurityException](https://developer.android.com/reference/java/lang/SecurityException)
溜哮。注:迄今為止滔金,這種限制尚不能完全執(zhí)行色解。應(yīng)用仍可能使用原生 API 或
[File](https://developer.android.com/reference/java/io/File)
API 來(lái)修改它們的私有目錄權(quán)限。但是餐茵,我們強(qiáng)烈反對(duì)放寬私有目錄的權(quán)限科阎。 傳遞軟件包網(wǎng)域外的
file://
URI 可能給接收器留下無(wú)法訪問(wèn)的路徑。因此忿族,嘗試傳遞file://
URI 會(huì)觸發(fā)FileUriExposedException
锣笨。分享私有文件內(nèi)容的推薦方法是使用[FileProvider](https://developer.android.com/reference/android/support/v4/content/FileProvider)
。[DownloadManager](https://developer.android.com/reference/android/app/DownloadManager)
不再按文件名分享私人存儲(chǔ)的文件道批。舊版應(yīng)用在訪問(wèn)[COLUMN_LOCAL_FILENAME](https://developer.android.com/reference/android/app/DownloadManager#COLUMN_LOCAL_FILENAME)
時(shí)可能出現(xiàn)無(wú)法訪問(wèn)的路徑错英。面向 Android 7.0 或更高版本的應(yīng)用在嘗試訪問(wèn)[COLUMN_LOCAL_FILENAME](https://developer.android.com/reference/android/app/DownloadManager#COLUMN_LOCAL_FILENAME)
時(shí)會(huì)觸發(fā)[SecurityException](https://developer.android.com/reference/java/lang/SecurityException)
。通過(guò)使用[DownloadManager.Request.setDestinationInExternalFilesDir()](https://developer.android.com/reference/android/app/DownloadManager.Request#setDestinationInExternalFilesDir(android.content.Context,%20java.lang.String,%20java.lang.String))
或[DownloadManager.Request.setDestinationInExternalPublicDir()](https://developer.android.com/reference/android/app/DownloadManager.Request#setDestinationInExternalPublicDir(java.lang.String,%20java.lang.String))
將下載位置設(shè)置為公共位置的舊版應(yīng)用仍可以訪問(wèn)[COLUMN_LOCAL_FILENAME](https://developer.android.com/reference/android/app/DownloadManager#COLUMN_LOCAL_FILENAME)
中的路徑隆豹,但是我們強(qiáng)烈反對(duì)使用這種方法椭岩。對(duì)于由[DownloadManager](https://developer.android.com/reference/android/app/DownloadManager)
公開(kāi)的文件,首選的訪問(wèn)方式是使用[ContentResolver.openFileDescriptor()](https://developer.android.com/reference/android/content/ContentResolver#openFileDescriptor(android.net.Uri,%20java.lang.String))
璃赡。
在應(yīng)用間共享文件
對(duì)于面向 Android 7.0 的應(yīng)用判哥,Android 框架執(zhí)行的 [StrictMode](https://developer.android.com/reference/android/os/StrictMode)
API 政策禁止在您的應(yīng)用外部公開(kāi) file://
URI。如果一項(xiàng)包含文件 URI 的 intent 離開(kāi)您的應(yīng)用鉴吹,則應(yīng)用出現(xiàn)故障姨伟,并出現(xiàn) FileUriExposedException
異常。
要在應(yīng)用間共享文件豆励,您應(yīng)發(fā)送一項(xiàng) content://
URI,并授予 URI 臨時(shí)訪問(wèn)權(quán)限瞒渠。進(jìn)行此授權(quán)的最簡(jiǎn)單方式是使用 [FileProvider](https://developer.android.com/reference/android/support/v4/content/FileProvider)
類良蒸。如需了解有關(guān)權(quán)限和共享文件的詳細(xì)信息,請(qǐng)參閱共享文件伍玖。
無(wú)障礙改進(jìn)
為提高平臺(tái)對(duì)于視力不佳或視力受損用戶的易用性嫩痰,Android 7.0 做出了一些更改。這些更改一般并不要求更改您的應(yīng)用代碼窍箍,不過(guò)您應(yīng)仔細(xì)檢查并使用您的應(yīng)用測(cè)試這些功能串纺,以評(píng)估它們對(duì)用戶體驗(yàn)的潛在影響。
屏幕縮放
Android 7.0 支持用戶設(shè)置顯示尺寸椰棘,以放大或縮小屏幕上的所有元素纺棺,從而提升設(shè)備對(duì)視力不佳用戶的可訪問(wèn)性。用戶無(wú)法將屏幕縮放至低于最小屏幕寬度 sw320dp邪狞,該寬度是 Nexus 4 的寬度祷蝌,也是常規(guī)中等大小手機(jī)的寬度。
當(dāng)設(shè)備密度發(fā)生更改時(shí)帆卓,系統(tǒng)會(huì)以如下方式通知正在運(yùn)行的應(yīng)用:
- 如果是面向 API 級(jí)別 23 或更低版本系統(tǒng)的應(yīng)用巨朦,系統(tǒng)會(huì)自動(dòng)終止其所有后臺(tái)進(jìn)程米丘。這意味著如果用戶切換離開(kāi)此類應(yīng)用,轉(zhuǎn)而打開(kāi) Settings 屏幕并更改 Display size 設(shè)置糊啡,則系統(tǒng)會(huì)像處理內(nèi)存不足的情況一樣終止該應(yīng)用拄查。如果應(yīng)用具有任何前臺(tái)進(jìn)程,則系統(tǒng)會(huì)如處理運(yùn)行時(shí)更改中所述將配置變更通知給這些進(jìn)程棚蓄,就像對(duì)待設(shè)備屏幕方向變更一樣靶累。
- 如果是面向 Android 7.0 的應(yīng)用,則其所有進(jìn)程(前臺(tái)和后臺(tái))都會(huì)收到有關(guān)配置變更的通知癣疟,如處理運(yùn)行時(shí)更改中所述挣柬。
大多數(shù)應(yīng)用并不需要進(jìn)行任何更改即可支持此功能,不過(guò)前提是這些應(yīng)用遵循 Android 最佳做法睛挚。具體要檢查的事項(xiàng):
在屏幕寬度為
[sw320dp](https://developer.android.com/guide/topics/resources/providing-resources)
的設(shè)備上測(cè)試您的應(yīng)用邪蛔,并確保其充分運(yùn)行。-
當(dāng)設(shè)備配置發(fā)生變更時(shí)扎狱,更新任何與密度相關(guān)的緩存信息侧到,例如緩存位圖或從網(wǎng)絡(luò)加載的資源。當(dāng)應(yīng)用從暫停狀態(tài)恢復(fù)運(yùn)行時(shí)淤击,檢查配置變更匠抗。
注:如果您要緩存與配置相關(guān)的數(shù)據(jù),則最好也包括相關(guān)元數(shù)據(jù)污抬,例如該數(shù)據(jù)對(duì)應(yīng)的屏幕尺寸或像素密度汞贸。保存這些元數(shù)據(jù)便于您在配置變更后決定是否需要刷新緩存數(shù)據(jù)。
避免用像素單位指定尺寸印机,因?yàn)橄袼夭粫?huì)隨屏幕密度縮放矢腻。應(yīng)改為使用與密度無(wú)關(guān)像素 (
dp
) 單位指定尺寸。
設(shè)置向?qū)е械囊曈X(jué)設(shè)置
Android 7.0 在“Welcome”屏幕中加入了“Vision Settings”射赛,用戶可以在新設(shè)備上設(shè)置以下無(wú)障礙功能設(shè)置:Magnification gesture多柑、Font size、Display size 和話語(yǔ)提示楣责。此項(xiàng)變更讓您可以更容易發(fā)現(xiàn)與不同屏幕設(shè)置有關(guān)的錯(cuò)誤竣灌。要評(píng)估此功能的影響,您應(yīng)在啟用這些設(shè)置的狀態(tài)下測(cè)試應(yīng)用秆麸。您可以在 Settings > Accessibility 中找到這些設(shè)置初嘹。
NDK 應(yīng)用鏈接至平臺(tái)庫(kù)
從 Android 7.0 開(kāi)始,系統(tǒng)將阻止應(yīng)用動(dòng)態(tài)鏈接非公開(kāi) NDK 庫(kù)蛔屹,這種庫(kù)可能會(huì)導(dǎo)致您的應(yīng)用崩潰削樊。此行為變更旨在為跨平臺(tái)更新和不同設(shè)備提供統(tǒng)一的應(yīng)用體驗(yàn)。即使您的代碼可能不會(huì)鏈接私有庫(kù),但您的應(yīng)用中的第三方靜態(tài)庫(kù)可能會(huì)這么做漫贞。因此甸箱,所有開(kāi)發(fā)者都應(yīng)進(jìn)行相應(yīng)檢查,確保他們的應(yīng)用不會(huì)在運(yùn)行 Android 7.0 的設(shè)備上崩潰迅脐。如果您的應(yīng)用使用原生代碼芍殖,則只能使用公開(kāi) NDK API。
您的應(yīng)用可通過(guò)以下三種方式嘗試訪問(wèn)私有平臺(tái) API:
- 您的應(yīng)用直接訪問(wèn)私有平臺(tái)庫(kù)谴蔑。您應(yīng)更新您的應(yīng)用以添加該應(yīng)用的庫(kù)副本豌骏,或使用公開(kāi) NDK API。
- 您的應(yīng)用使用一個(gè)可訪問(wèn)私有平臺(tái)庫(kù)的第三方庫(kù)隐锭。即使您確定您的應(yīng)用不會(huì)直接訪問(wèn)私有庫(kù)窃躲,您仍應(yīng)針對(duì)此情景測(cè)試您的應(yīng)用。
- 您的應(yīng)用引用一個(gè)其 APK 中未包含的庫(kù)钦睡。例如蒂窒,如果您嘗試使用您自己的 OpenSSL 副本,但忘記將它與應(yīng)用的 APK 進(jìn)行捆綁荞怒,則可能會(huì)出現(xiàn)此情況洒琢。正常情況下,此應(yīng)用可在包含
libcrypto.so
的 Android 平臺(tái)版本上運(yùn)行褐桌。不過(guò)衰抑,此應(yīng)用在不包含此庫(kù)的新版 Android(例如,Android 6.0 和更高的版本)上會(huì)崩潰荧嵌。為修復(fù)此問(wèn)題呛踊,請(qǐng)確保您的 APK 捆綁您的所有非 NDK 庫(kù)。
應(yīng)用不應(yīng)使用 NDK 中未包含的原生庫(kù)完丽,因?yàn)檫@些庫(kù)可能會(huì)發(fā)生更改或在不同 Android 版本之間的可用性不同恋技。例如,從 OpenSSL 切換至 BoringSSL 即屬于此類更改逻族。此外,由于不屬于 NDK 中的平臺(tái)庫(kù)沒(méi)有兼容性要求骄崩,因此不同的設(shè)備可能提供不同級(jí)別的兼容性聘鳞。
為降低此限制可能對(duì)當(dāng)前發(fā)布的應(yīng)用的影響,面向 API 級(jí)別 23 或更低級(jí)別的應(yīng)用在 Android N 上可暫時(shí)訪問(wèn)頗為常用的一組庫(kù)要拂,例如 libandroid_runtime.so
抠璃、libcutils.so
、libcrypto.so
和 libssl.so
脱惰。如果您的應(yīng)用加載其中某個(gè)庫(kù)搏嗡,logcat 會(huì)生成一個(gè)警告,并在目標(biāo)設(shè)備上顯示一個(gè) Toast 來(lái)通知您。如果您看到這些警告采盒,您應(yīng)更新您的應(yīng)用以添加該應(yīng)用自己的庫(kù)副本旧乞,或僅使用公開(kāi) NDK API。將來(lái)發(fā)布的 Android 平臺(tái)可能會(huì)完全限制對(duì)私有庫(kù)的使用磅氨,并導(dǎo)致您的應(yīng)用崩潰尺栖。
所有應(yīng)用在調(diào)用既非公開(kāi)又不可暫時(shí)訪問(wèn)的 API 時(shí)都會(huì)生成一個(gè)運(yùn)行時(shí)錯(cuò)誤。結(jié)果就是 System.loadLibrary
和 dlopen(3)
同時(shí)返回 NULL
烦租,并可能導(dǎo)致您的應(yīng)用崩潰延赌。您應(yīng)檢查應(yīng)用代碼以移除對(duì)私有平臺(tái) API 的使用,并使用預(yù)覽版設(shè)備或模擬器全面測(cè)試應(yīng)用叉橱。如果您不確定您的應(yīng)用是否使用私有庫(kù)挫以,您可以檢查 logcat 以識(shí)別運(yùn)行時(shí)錯(cuò)誤。
下表描述的是根據(jù)應(yīng)用使用的私有原生庫(kù)及其目標(biāo) API 級(jí)別 (android:targetSdkVersion
)窃祝,應(yīng)用預(yù)期顯示的行為掐松。
| 庫(kù) | 目標(biāo) API 級(jí)別 | 通過(guò)動(dòng)態(tài)鏈接器進(jìn)行運(yùn)行時(shí)訪問(wèn) | N Developer Preview 行為 | 最終 Android N 版本行為 | 未來(lái)的 Android 平臺(tái)行為 |
| 公開(kāi) NDK | 任意 | 可訪問(wèn) | 合乎預(yù)期 | 合乎預(yù)期 | 合乎預(yù)期 |
| 私有(暫時(shí)可訪問(wèn)的私有庫(kù)) | 23 或更低 | 暫時(shí)可訪問(wèn) | 合乎預(yù)期,但您會(huì)在目標(biāo)設(shè)備上收到一個(gè) logcat 警告和一條消息锌杀。 | 合乎預(yù)期甩栈,但您會(huì)收到一個(gè) logcat 警告。 | 運(yùn)行時(shí)錯(cuò)誤 |
| 私有(暫時(shí)可訪問(wèn)的私有庫(kù)) | 24 或更高 | 受限 | 運(yùn)行時(shí)錯(cuò)誤 | 運(yùn)行時(shí)錯(cuò)誤 | 運(yùn)行時(shí)錯(cuò)誤 |
| 私有(其他) | 任意 | 受限 | 運(yùn)行時(shí)錯(cuò)誤 | 運(yùn)行時(shí)錯(cuò)誤 | 運(yùn)行時(shí)錯(cuò)誤 |
檢查您的應(yīng)用是否使用私有庫(kù)
為幫助您識(shí)別加載私有庫(kù)的問(wèn)題糕再,logcat 可能會(huì)生成一個(gè)警告或運(yùn)行時(shí)錯(cuò)誤量没。例如,如果您的應(yīng)用面向 API 級(jí)別 23 或更低級(jí)別突想,并在運(yùn)行 Android 7.0 的設(shè)備上嘗試訪問(wèn)私有庫(kù)殴蹄,您可能會(huì)看到一個(gè)類似于下面所示的警告:
03-21 17:07:51.502 31234 31234 W linker : library "libandroid_runtime.so"
("/system/lib/libandroid_runtime.so") needed or dlopened by
"/data/app/com.popular-app.android-2/lib/arm/libapplib.so" is not accessible
for the namespace "classloader-namespace" - the access is temporarily granted
as a workaround for http://b/26394120
這些 logcat 警告通知您哪個(gè)庫(kù)正在嘗試訪問(wèn)私有平臺(tái) API,但不會(huì)導(dǎo)致您的應(yīng)用崩潰猾担。但是袭灯,如果應(yīng)用面向 API 級(jí)別 24 或更高級(jí)別,logcat 會(huì)生成以下運(yùn)行時(shí)錯(cuò)誤绑嘹,您的應(yīng)用可能會(huì)崩潰:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libcutils.so"
("/system/lib/libcutils.so") needed or dlopened by
"/system/lib/libnativeloader.so" is not accessible for the namespace
"classloader-namespace"
at java.lang.Runtime.loadLibrary0(Runtime.java:977)
at java.lang.System.loadLibrary(System.java:1602)
如果您的應(yīng)用使用動(dòng)態(tài)鏈接到私有平臺(tái) API 的第三方庫(kù)稽荧,您可能也會(huì)看到上述 logcat 輸出。利用 Android 7.0DK 中的 readelf 工具工腋,您可以通過(guò)運(yùn)行以下命令生成給定 .so
文件的所有動(dòng)態(tài)鏈接的共享庫(kù)列表:
aarch64-linux-android-readelf -dW libMyLibrary.so
更新您的應(yīng)用
通過(guò)下面的一些步驟姨丈,您可以修復(fù)上述類型的錯(cuò)誤并確保您的應(yīng)用不會(huì)在將來(lái)的更新版平臺(tái)上崩潰:
- 如果您的應(yīng)用使用私有平臺(tái)庫(kù),您應(yīng)更新它擅腰,以添加該應(yīng)用自己的庫(kù)副本或使用公開(kāi) NDK API蟋恬。
- 如果您的應(yīng)用使用訪問(wèn)私有符號(hào)的第三方庫(kù),則聯(lián)系庫(kù)作者以更新庫(kù)趁冈。
- 請(qǐng)確保將您的所有非 NDK 庫(kù)與您的 APK 打包在一起歼争。
- 使用標(biāo)準(zhǔn) JNI 函數(shù)而非來(lái)自
libandroid_runtime.so
的getJavaVM
和getJNIEnv
:
AndroidRuntime::getJavaVM -> GetJavaVM from <jni.h>
AndroidRuntime::getJNIEnv -> JavaVM::GetEnv or
JavaVM::AttachCurrentThread from <jni.h>.
- 使用
__system_property_get
而非來(lái)自libcutils.so
的私有property_get
符號(hào)拜马。為此,請(qǐng)使用__system_property_get
及以下 include 函數(shù):
#include <sys/system_properties.h>
**注**:系統(tǒng)屬性的可用性和內(nèi)容未通過(guò) CTS 進(jìn)行測(cè)試沐绒。應(yīng)執(zhí)行進(jìn)一步修復(fù)以避免同時(shí)使用這些屬性俩莽。
- 使用來(lái)自
libcrypto.so
的SSL_ctrl
符號(hào)的本地版本。例如洒沦,您應(yīng)在您的.so
文件中靜態(tài)鏈接libcyrpto.a
豹绪,或從 BoringSSL/OpenSSL 添加一個(gè)動(dòng)態(tài)鏈接的libcrypto.so
版本,并將其打包到您的 APK 中申眼。
Android for Work
Android 7.0 包含一些針對(duì)面向 Android for Work 的應(yīng)用的變更瞒津,包括對(duì)證書(shū)安裝、密碼重置括尸、二級(jí)用戶管理巷蚪、設(shè)備標(biāo)識(shí)符訪問(wèn)權(quán)限的變更。如果您是要針對(duì) Android for Work 環(huán)境開(kāi)發(fā)應(yīng)用濒翻,則應(yīng)仔細(xì)檢查這些變更并相應(yīng)地修改您的應(yīng)用屁柏。
- 您必須先安裝授權(quán)證書(shū)安裝程序,然后 DPC 才能對(duì)其進(jìn)行設(shè)置有送。對(duì)于面向 N SDK 的配置文件和設(shè)備所有者應(yīng)用淌喻,您應(yīng)在設(shè)備規(guī)范控制器 (DPC) 調(diào)用
DevicePolicyManager.setCertInstallerPackage()
之前安裝授權(quán)證書(shū)安裝程序。如果尚未安裝此安裝程序雀摘,則系統(tǒng)會(huì)引發(fā)IllegalArgumentException
裸删。 - 針對(duì)設(shè)備管理員的重置密碼限制現(xiàn)在也適用于配置文件所有者。設(shè)備管理員無(wú)法再使用
DevicePolicyManager.resetPassword()
來(lái)清除或更改已經(jīng)設(shè)置的密碼阵赠。設(shè)備管理員仍可以設(shè)置密碼涯塔,但只能在設(shè)備沒(méi)有密碼、PIN 碼或圖案時(shí)這樣做清蚀。 - 即使設(shè)置了限制匕荸,設(shè)備所有者和配置文件所有者仍可以管理帳戶。而且枷邪,即使具有
DISALLOW_MODIFY_ACCOUNTS
用戶限制榛搔,設(shè)備所有者和配置文件所有者仍可調(diào)用 Account Management API。 - 設(shè)備所有者可以更輕松地管理二級(jí)用戶东揣。當(dāng)設(shè)備在設(shè)備所有者模式下運(yùn)行時(shí)药薯,系統(tǒng)將自動(dòng)設(shè)置
DISALLOW_ADD_USER
限制。這樣可以防止用戶創(chuàng)建非托管二級(jí)用戶救斑。此外,CreateUser()
和createAndInitializeUser()
方法已棄用真屯,取而代之的是DevicePolicyManager.createAndManageUser()
方法脸候。 - 設(shè)備所有者可以訪問(wèn)設(shè)備標(biāo)識(shí)符。設(shè)備所有者可以使用
DevicePolicyManagewr.getWifiMacAddress()
訪問(wèn)設(shè)備的 WLAN MAC 地址。如果設(shè)備上從未啟用 WLAN运沦,則此方法將返回一個(gè)null
值泵额。 - 工作模式設(shè)置控制工作應(yīng)用訪問(wèn)。當(dāng)工作模式關(guān)閉時(shí)携添,系統(tǒng)啟動(dòng)器通過(guò)使工作應(yīng)用顯示為灰色來(lái)指示它們不可用嫁盲。啟用工作模式會(huì)再次恢復(fù)正常行為。
- 從 Settings UI 安裝包含客戶端證書(shū)鏈和對(duì)應(yīng)的私鑰的 PKCS #12 文件時(shí)烈掠,系統(tǒng)不再將該證書(shū)鏈中的 CA 證書(shū)安裝到受信任的憑據(jù)存儲(chǔ)空間羞秤。當(dāng)應(yīng)用稍后嘗試檢索客戶端證書(shū)鏈時(shí),這不會(huì)影響
[KeyChain.getCertificateChain()](https://developer.android.com/reference/android/security/KeyChain#getCertificateChain(android.content.Context,%20java.lang.String))
的結(jié)果左敌。如果需要瘾蛋,使用 .crt 或 .cer 文件擴(kuò)展名的 DER 編碼格式通過(guò) Settings UI 單獨(dú)將 CA 證書(shū)安裝到受信任的憑據(jù)存儲(chǔ)空間。 - 從 Android 7.0 開(kāi)始矫限,可針對(duì)每個(gè)用戶管理指紋登記和存儲(chǔ)空間哺哼。如果配置文件所有者的設(shè)備規(guī)范客戶端 (DPC) 面向 Android N 設(shè)備上的 Android N 之前的版本,則用戶仍可以在該設(shè)備上設(shè)置指紋叼风,但工作應(yīng)用不能訪問(wèn)設(shè)備指紋取董。當(dāng) DPC 面向 Android N 和更高版本時(shí),用戶可以通過(guò)轉(zhuǎn)到 Settings > Security > Work profile security 專門(mén)為托管配置文件設(shè)置指紋无宿。
-
DevicePolicyManager.getStorageEncryptionStatus()
返回新的加密狀態(tài)ENCRYPTION_STATUS_ACTIVE_PER_USER
茵汰,以表明加密處于活動(dòng)狀態(tài),且加密密鑰與用戶關(guān)聯(lián)懈贺。僅當(dāng) DPC 面向 API 級(jí)別 24 和更高級(jí)別時(shí)才會(huì)返回新的狀態(tài)经窖。對(duì)于面向更早的 API 級(jí)別的應(yīng)用,即使加密密鑰是用戶或配置文件特有的梭灿,系統(tǒng)也會(huì)返回ENCRYPTION_STATUS_ACTIVE
画侣。 - 在 Android 7.0 中,如果設(shè)備通過(guò)單獨(dú)的工作挑戰(zhàn)安裝了托管配置文件堡妒,則原本通常會(huì)影響整個(gè)設(shè)備的多個(gè)方法將會(huì)改變其行為方式配乱。這些方法將僅應(yīng)用于托管配置文件,而不是影響整個(gè)設(shè)備皮迟。(此類方法的完整列表位于
[DevicePolicyManager.getParentProfileInstance()](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getParentProfileInstance(android.content.ComponentName))
文檔中搬泥。)例如,[DevicePolicyManager.lockNow()](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#lockNow())
只鎖定托管配置文件伏尼,而不是鎖定整個(gè)設(shè)備忿檩。對(duì)于上述每個(gè)方法,您可以通過(guò)對(duì)[DevicePolicyManager](https://developer.android.com/reference/android/app/admin/DevicePolicyManager)
的父實(shí)例調(diào)用該方法來(lái)獲取以前的行為爆阶;您可以通過(guò)調(diào)用[DevicePolicyManager.getParentProfileInstance()](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#getParentProfileInstance(android.content.ComponentName))
獲取此父項(xiàng)燥透。例如沙咏,如果您調(diào)用父實(shí)例的[lockNow()](https://developer.android.com/reference/android/app/admin/DevicePolicyManager#lockNow())
方法,則整個(gè)設(shè)備將被鎖定班套。
如需了解有關(guān) Android 7.0 中針對(duì) Android for Work 所做變更的詳細(xì)信息肢藐,請(qǐng)參閱 Android for Work 更新。
注解保留
Android 7.0 修復(fù)了一個(gè)注解可見(jiàn)性被忽略的錯(cuò)誤吱韭。這種問(wèn)題會(huì)導(dǎo)致應(yīng)用可在運(yùn)行時(shí)訪問(wèn)原本不允許訪問(wèn)的注解吆豹。這些注解包括:
-
VISIBILITY_BUILD
:僅應(yīng)編譯時(shí)可見(jiàn)。 -
VISIBILITY_SYSTEM
:運(yùn)行時(shí)應(yīng)可見(jiàn)理盆,但僅限底層系統(tǒng)痘煤。
如果您的應(yīng)用依賴這種行為,請(qǐng)為運(yùn)行時(shí)必須可用的注解添加保留政策熏挎。您可通過(guò)使用 @Retention(RetentionPolicy.RUNTIME)
來(lái)執(zhí)行此操作速勇。
其他重要說(shuō)明
-
如果一個(gè)應(yīng)用在 Android 7.0 上運(yùn)行,但卻是針對(duì)更低 API 級(jí)別開(kāi)發(fā)的坎拐,那么在用戶更改顯示尺寸時(shí)烦磁,系統(tǒng)將終止此應(yīng)用進(jìn)程。應(yīng)用必須能夠妥善處理此情景哼勇。否則都伪,當(dāng)用戶從最近使用記錄中恢復(fù)運(yùn)行應(yīng)用時(shí),應(yīng)用將會(huì)出現(xiàn)崩潰現(xiàn)象积担。
您應(yīng)測(cè)試應(yīng)用以確保不會(huì)發(fā)生此行為陨晶。要進(jìn)行此測(cè)試,您可以通過(guò) DDMS 手動(dòng)終止應(yīng)用帝璧,以造成相同的崩潰現(xiàn)象先誉。
在密度發(fā)生更改時(shí),系統(tǒng)不會(huì)自動(dòng)終止面向 N 及更高版本的應(yīng)用的烁;不過(guò)褐耳,這些應(yīng)用仍可能對(duì)配置變更做出不良響應(yīng)。
Android 7.0 上的應(yīng)用應(yīng)能夠妥善處理配置變更渴庆,并且在后續(xù)啟動(dòng)時(shí)不會(huì)出現(xiàn)崩潰現(xiàn)象铃芦。您可以通過(guò)更改字體大小 (Setting >Display > Font size) 并隨后從最近使用記錄中恢復(fù)運(yùn)行應(yīng)用,來(lái)驗(yàn)證應(yīng)用行為襟雷。
由于之前的 Android 版本中的一項(xiàng)錯(cuò)誤刃滓,系統(tǒng)未能將對(duì)主線程上的一個(gè) TCP 套接字的寫(xiě)入操作舉報(bào)為違反嚴(yán)格模式。Android 7.0 修復(fù)了此錯(cuò)誤耸弄。呈現(xiàn)出這種行為的應(yīng)用現(xiàn)在會(huì)引發(fā)
android.os.NetworkOnMainThreadException
咧虎。一般情況下,我們不建議在主線程上執(zhí)行網(wǎng)絡(luò)操作计呈,因?yàn)檫@些操作通常會(huì)出現(xiàn)可能導(dǎo)致 ANR 和卡頓的高尾延遲老客。Debug.startMethodTracing()
方法系列現(xiàn)在默認(rèn)在您的共享存儲(chǔ)空間上的軟件包特定目錄中存儲(chǔ)輸出僚饭,而非 SD 卡根目錄。這意味著應(yīng)用不再需要請(qǐng)求WRITE_EXTERNAL_STORAGE
權(quán)限來(lái)使用這些 API 胧砰。許多平臺(tái) API 現(xiàn)在開(kāi)始檢查在
[Binder](https://developer.android.com/reference/android/os/Binder)
事務(wù)間發(fā)送的大負(fù)載,系統(tǒng)現(xiàn)在會(huì)將TransactionTooLargeExceptions
作為RuntimeExceptions
再次引發(fā)苇瓣,而不再只是默默記錄或抑制它們尉间。一個(gè)常見(jiàn)例子是在[Activity.onSaveInstanceState()](https://developer.android.com/reference/android/app/Activity#onSaveInstanceState(android.os.Bundle))
上存儲(chǔ)過(guò)多數(shù)據(jù),導(dǎo)致ActivityThread.StopInfo
在您的應(yīng)用面向 Android 7.0 時(shí)引發(fā)RuntimeException
芽淡。-
如果應(yīng)用向
[View](https://developer.android.com/reference/android/view/View)
發(fā)布[Runnable](https://developer.android.com/reference/java/lang/Runnable)
任務(wù)恳蹲,并且[View](https://developer.android.com/reference/android/view/View)
未附加到窗口说墨,系統(tǒng)會(huì)用[View](https://developer.android.com/reference/android/view/View)
為[Runnable](https://developer.android.com/reference/java/lang/Runnable)
任務(wù)排隊(duì);在[View](https://developer.android.com/reference/android/view/View)
附加到窗口之前眠副,不會(huì)執(zhí)行[Runnable](https://developer.android.com/reference/java/lang/Runnable)
任務(wù)。此行為會(huì)修復(fù)以下錯(cuò)誤:- 如果一項(xiàng)應(yīng)用是從并非預(yù)期窗口 UI 線程的其他線程發(fā)布到
[View](https://developer.android.com/reference/android/view/View)
竣稽,則[Runnable](https://developer.android.com/reference/java/lang/Runnable)
可能會(huì)因此運(yùn)行錯(cuò)誤的線程囱怕。 - 如果
[Runnable](https://developer.android.com/reference/java/lang/Runnable)
任務(wù)是從并非環(huán)路線程的其他線程發(fā)布,則應(yīng)用可能會(huì)曝光[Runnable](https://developer.android.com/reference/java/lang/Runnable)
任務(wù)毫别。
- 如果一項(xiàng)應(yīng)用是從并非預(yù)期窗口 UI 線程的其他線程發(fā)布到
如果 Android 7.0 上一項(xiàng)有
[DELETE_PACKAGES](https://developer.android.com/reference/android/Manifest.permission#DELETE_PACKAGES)
權(quán)限的應(yīng)用嘗試刪除一個(gè)軟件包娃弓,但另一項(xiàng)應(yīng)用已經(jīng)安裝了這個(gè)軟件包,則系統(tǒng)需要用戶進(jìn)行確認(rèn)岛宦。在這種情況下台丛,應(yīng)用在調(diào)用[PackageInstaller.uninstall()](https://developer.android.com/reference/android/content/pm/PackageInstaller#uninstall(android.content.pm.VersionedPackage,%20android.content.IntentSender))
時(shí)預(yù)計(jì)的返回狀態(tài)應(yīng)為[STATUS_PENDING_USER_ACTION](https://developer.android.com/reference/android/content/pm/PackageInstaller#STATUS_PENDING_USER_ACTION)
。名為 Crypto 的 JCA 提供程序已棄用砾肺,因?yàn)樗鼉H有的 SHA1PRNG 算法為弱加密挽霉。應(yīng)用無(wú)法再使用 SHA1PRNG(不安全地)派生密鑰,因?yàn)椴辉偬峁┐颂峁┏绦虮渫簟H缧枇私庠敿?xì)信息侠坎,請(qǐng)參閱博文 Android N 中已棄用“Crypto”安全提供程序。