譯者:李鑫
原文:Random Musings on the N Developer Preview
本文為極客學(xué)院Wiki組織翻譯,轉(zhuǎn)載請注明出處。
時間:2016.3.21
每當谷歌發(fā)布新的開發(fā)者預(yù)覽版時,我都會在 API 差異報告和高級別概述查找一番,看看是否存在一些值得開發(fā)者更多關(guān)注的東西,重點查找一些開發(fā)者可能都會使用的主流特性。我也會特別留意一些關(guān)注度可能不是很高的東西,因為有些東西都已經(jīng)淹沒在 Java 文檔中了。
這次發(fā)布的 N 有點像冰山一角。概要中所展示的內(nèi)容雖然有趣,但到正式版發(fā)布之時,改動可能會非常多。這種情況可能跟轉(zhuǎn)換到 OpenJDK 有點關(guān)系,詳情請參看我之前的隨筆。
多窗口功能的支持將在短期內(nèi)獲得很多媒體的關(guān)注。多窗口支持是板上釘釘?shù)牧?/strong>。除非 targetSdkVersion
為 N(今天,可能最終是 24)并且你特別聲明不想讓 activity 被調(diào)整尺寸,否則你的應(yīng)用將一定能被用戶調(diào)整尺寸。這里還有一些例外情況,尤其是能夠通過 screenOrientation
修改原始方位的 activity。但總的來說,不管喜歡與否,activity 將來都可以被調(diào)整尺寸。而且,用戶也希望能夠調(diào)整你的 activity 的尺寸。綜合各種形式的因素考慮,這一特性大概應(yīng)盡早地經(jīng)常進行測試。
安卓準備進入桌面市場的消息已經(jīng)不是新聞了。多窗口支持明顯就是為了桌面方式應(yīng)用而設(shè)計的。盡管現(xiàn)在的媒體可能更為關(guān)注分屏模式,但我猜到了五月底,媒體的關(guān)注焦點將是“自由形態(tài)”(freeform)模式(大型設(shè)備制造商將能選擇啟用“自由形態(tài)”模式,從而使用戶自由地定義每個 activity 的尺寸)。按照谷歌對該模式的闡述,很可能是針對窗口化桌面應(yīng)用。但我考慮,除了多窗口支持之外,以下改動確實標志著安卓將開始進入桌面領(lǐng)域:
現(xiàn)在可以對剪切、復(fù)制、粘貼以及 Activity
中的 onProvideKeyboardShortcuts()
指定專用的鍵碼,暗示將更為關(guān)注硬件的鍵盤輸入功能。
現(xiàn)在有了 PointerIcon
,以及 View
中的指針捕獲鉤子,暗示將更為關(guān)注鼠標/觸控板的輸入功能。
FEATURE_ETHERNET
,以及大概會有的對應(yīng)的 <uses-feature>
選項,暗示將更多關(guān)注硬連線的網(wǎng)絡(luò)連接。 Android 6.0 引入了 Doze (瞌睡)模式,這曾讓一些開發(fā)者感到非常吃驚。那時,該模式被限制用于靜止狀態(tài)的設(shè)備中(比如晚上放在了床頭幾上)。到了 Android N 時代,只要設(shè)備不處于充電狀態(tài),隨時都可以啟用 Doze 模式——即使設(shè)備處于移動狀態(tài)。這一模式改變的不是應(yīng)用的行為,而是應(yīng)用受此影響的程度,另外一個值得注意的問題是,該模式可能會觸發(fā)用戶支持問題的頻率。
多語言環(huán)境支持也使得資源協(xié)議變得更為復(fù)雜。需要你更多地關(guān)注對語系的完整翻譯,而不能是部分的。如果有些語系丟失了一個字符串,用戶設(shè)備就可能馬上在默認的資源集中(如res/values/strings.xml
)用隨便一個字符串來代替它。在 N 中,用戶可能從次級語言環(huán)境中獲取字符串。如果在翻譯集中出現(xiàn)的漏洞足夠多的話,那么用戶設(shè)備屏幕上顯示的語言就會完全不同了。一定要確保翻譯的完整性,無論是引入翻譯,還是添加面向用戶字符串時。
還是跟多語言環(huán)境支持有關(guān),如果你的應(yīng)用設(shè)置會覆蓋用戶設(shè)備所用的語言環(huán)境,那么在使用 N 時請全面測試。
據(jù)數(shù)據(jù)流量節(jié)省功能(Data Saver)文檔顯示,應(yīng)用需要“對于后臺數(shù)據(jù)使用上的限制,要恰當?shù)靥幚怼?。對此我理解為,?shù)據(jù)流量節(jié)省功能有點像是應(yīng)用備用功能,除非用戶主動使用應(yīng)用,否則訪問互聯(lián)網(wǎng)功能受限。這一功能同樣也需要全面測試才行。
你可能會忍不住使用 ACTION_IGNORE_BACKGROUND_DATA_RESTRICTIONS_SETTINGS
去引導(dǎo)用戶將應(yīng)用添加到 Data Saver 白名單中,以便可以正常進行后臺網(wǎng)絡(luò)訪問。但請記住,谷歌也有類似的電池電量白名單……如果使用那個行為,將使得應(yīng)用被 Play Store 封殺。目前還沒有 Data Saver 白名單的相關(guān)文檔說明……但是,再說一句,在Android 6.0 發(fā)布前,對于進入電池電量節(jié)省白名單的請求,谷歌方面也沒有明說會封殺應(yīng)用。
總體來說,網(wǎng)絡(luò)安全配置可以很有效地保護你的應(yīng)用。開發(fā)者們收到的有關(guān)介紹失效 X509TrustManager
實現(xiàn)的郵件中涉及到了一個有用的副作用。其中一些失效的TrustManager
實現(xiàn)已經(jīng)跟使用自簽名證書關(guān)聯(lián)到一起了。現(xiàn)在,你可以使用調(diào)試-重寫來允許應(yīng)用使用自簽名證書。如果我沒理解錯的話,這意味著可以在需要時(比如測試服務(wù)器)光明正大地使用自簽名證書,而不用再冒險在產(chǎn)品發(fā)布時支持這種證書。
所有典型的 JUnit 測試用例基類都被棄用,比如 ActivityInstrumentationTestCase2
和 ActivityTestCase
。如果你還沒有這樣做,那么差不多會在明年轉(zhuǎn)變成 JUnit4 測試支持。
目前有了一個新的 FileUriExposedException
。如果使用 file:
Uri
值就會拋出該異?!,F(xiàn)在還不完全清除何種情況下拋出。(2016-03-14 更新:如果使用 file:``Uri
值,則幾乎會拋出該異常)。StrictMode.VmPolicy.Builder
中的 penaltyDeathOnFileUriExposure()
據(jù)推測可能會觸發(fā)這個異常。但是,含混的措辭說明,或許 N(以及 Android 的未來版本)會采用默認拋出該異常的機制,就像拋出 NetworkOnMainThreadException
異常那樣。為了處理這個問題:
如果從第三方應(yīng)用中接受了 Uri
值,請做好對 content:
Uri
值的支持工作。不要犯傻地認為這些值都來自 MediaStore
或具有能夠獲取的文件路徑。請使用 openInputStream()
、getType()
以及帶有 ContentResolver
的 OpenableColumns
來使用 Uri
標識的內(nèi)容。
Uri
值發(fā)送到其他應(yīng)用中(ACTION_VIEW
、ACTION_SEND
,等等),請繼續(xù)continue moving over to content:
Uri
值。使用 FileProvider
,也許也可以輔以 我的 LegacyCompatCursorWrapper
(為了避免犯下前面提到的錯誤)。最低限度也要將你創(chuàng)建這些 Uri
值的方法隔離到未來可能更容易切換到 content:
Uri
值的位置下,以防止在生產(chǎn)環(huán)境下拋出 FileUriExposedException
異常。如果你在 BitmapFactory.Options
上使用 inPreferQualityOverSpeed
,那么現(xiàn)在看來,這已經(jīng)被廢棄了。相關(guān)文檔聲明,在 N 中標志會被忽略,因為“輸出將一直是高質(zhì)量的”。根據(jù)相關(guān)的報道,這種做法有點像是烏比岡湖效應(yīng),或者也可以說是一直處于憤怒狀態(tài)的綠巨人。
如果你看過 N 的 API 差異報告,可能會有點恐慌吧?興許會認為谷歌去除了 Html
類中的 fromHtml()
和 toHtml()
。這似乎是 API 差異報告措辭中的一個 Bug。那些方法還在。但確實由接受標志參數(shù)的額外方法所補充進來的,可以更好地解釋或生成 HTML。不過,這反而說明這一代碼經(jīng)過了徹底檢查,效果會非常出色。
StringBuilder
(以及遺留的 StringBuffer
)不再實現(xiàn) Appendable
。這似乎是報告中的一個 Bug,因為據(jù) Java 文檔顯示,它們依然能夠?qū)崿F(xiàn) Appendable
。因為在 Java 8 中它們能夠?qū)崿F(xiàn) Appendable
,所以這些類的安卓版本應(yīng)該也能繼續(xù)實現(xiàn) Appendable
。ACTION_OPEN_EXTERNAL_DIRECTORY
和 android.os.storage.StorageVolume
。據(jù)我所知,這一做法是為了避免 READ_EXTERNAL_STORAGE
和 WRITE_EXTERNAL_STORAGE
,并可能會通過請求用戶授予長期細粒度的許可,來允許直接訪問更多的可移動存儲。聽上去有點合理。但是,很多開發(fā)者依舊還在學(xué)習(xí)使用 Android 4.4 所引入的存儲訪問架構(gòu)( Storage Access Framework),以及在可移動存儲上采取同步限制。更為讓人困擾的是,預(yù)覽版中的 “進一步的詳細信息”(“For more information”)鏈接是空的。2016-03-10 更新: Ian Lake 指出,“scoped directory access” 文檔已經(jīng)不再更新了。
android.auditing.SecurityLog
似乎非常有意思(可以記錄 adb shell 命令等)。
AlarmManager
現(xiàn)在具有進程內(nèi)的警告。set()
、setExact()
和 setWindow()
都能接受 OnAlarmListener
,并能在時機到來時,在其上調(diào)用一個回調(diào)函數(shù)。
現(xiàn)在有了 commitNow()
選項,執(zhí)行同步的 FragmentTransaction
,而commit()
則是異步的。
android.webkit
包有了 ServiceWorker
相關(guān)類
WebSettings
有了 setDisabledActionModeMenuItems()
,說明可以限制一些標準的剪切/復(fù)制/粘貼操作。如果不打算讓這些操作干擾所要渲染的 Web 內(nèi)容,那么這個參數(shù)就非常有用了。
WebViewClient
上的 shouldOverrideUrlLoading(WebView, String)
被廢棄,取而代之的是shouldOverrideUrlLoading(WebView, WebResourceRequest)
。
AbsSeekBar
支持刻度線,我猜測是很大程度受益于 SeekBar
。
Chronometer
支持倒數(shù)計秒模式,通過 RemoteViews
包含在應(yīng)用小組件中。 Intent
有了 ACTION_PACKAGES_SUSPENDED
和 ACTION_PACKAGES_UNSUSPENDED
這兩個行為。目前還不清楚這一上下文中的 suspended 究竟是什么意思。更新 2016-03-14:Andriy Petruk 指出這可能跟 Android for Work 項目有關(guān)。
Intent
中定義了一個 ACTION_QUICK_VIEW
,用來“快速查看 URI 或 URI 列表”。但這樣一種查看器的具體含義,以及是否能應(yīng)用一個查看器等問題仍不可清楚,但我想具體的說明也很快會出現(xiàn)。
還有,什么是 AutomaticZenRule
?但我想 Phil Jackson 會贊成它。
目前很清楚的是,isolatedProcess
服務(wù)可以運行在單獨的權(quán)限較少的進程。N 提供了 externalService
,它要與 isolatedProcess
配合起來,能允許服務(wù)“在應(yīng)用包的調(diào)用過程中運行”。但這里所說的“在應(yīng)用包的調(diào)用過程中運行”到底指的是存儲,還是許可,還是其他的什么東西呢?
Android 將來的版本可能會不贊成使用額外的隱式廣播,以及未綁定的后臺服務(wù)?;谶@種猜測,應(yīng)避免或去除用于隱式廣播的聲明清單接收器中的依賴,同樣后臺服務(wù)也應(yīng)如此。
這一想法來源于在對 CONNECTIVITY_ACTION
改變(不能再在清單中注冊它了)的討論過程中。
谷歌可能將更多的隱式廣播轉(zhuǎn)移到了 registerReceiver()
-only bucket does not surprise me. 在某種程度上,我吃驚的是他們沒有及時針對這一點進行更多的修改。
讓我吃驚的是,未綁定服務(wù)可能失去支持了。
如果他們說棄用了 FLAG_START_STICKY
,我還可以理解?;蛘吒_地說,如果他們認為帶有服務(wù)的進程可能更快地被終止,我也可以理解。
將 IntentService
和服務(wù)的其他命令模式用法全部去除,在我看來是有點過頭了。 很顯然,他們想讓開發(fā)者把所有的后臺作業(yè)都塞進各個分散的類別中,利用專門的服務(wù)子類(比如JobScheduler
),以此來達成控制電池電量和內(nèi)存消耗的目的。
我對這一做法的前途深表擔心。
我猜 2016 年 8 月可能會發(fā)布一個版本,上下不超過一個月吧。開發(fā)者預(yù)覽版都比以前提早了幾個月,同樣,8 月也比一般發(fā)布新的主流 Andorid 版本的時間要早幾個月了。
另一本書的更新內(nèi)容中將開始介紹 N 開發(fā)者預(yù)覽版,本月晚些時候?qū)⒂枰怨肌?/p>
— 2016 年 3 月 9 日 Tweet