Android 4.4釋出了新的API併為使用者和開發者加入了新的特性
我的同事側重介紹一些大的改動細節,然而我更關注一些細節變化以及開發者在開發過程中可能會遇到的行為改變。
許可權
啟動快捷鍵
在API 19中 已經新增了INSTALL_SHORTCUT
和UNINSTALL_SHORTCUT
許可權進公佈的SDK 。公開這些許可權是必要的,它使得應用在裝置的載入介面直接新增或刪除快捷圖示。
這些許可權實際上並不是新功能。它們在Android 1.x 的時候就已經被定義好了,在那個時候這些許可權是被定義在初始化應用裡面而不是公開在SDK, 所以使用了新許可權的應用可以獲得許可權所設定的能力,同時也能執行在老版本的安卓裝置上。
外部儲存
外部儲存的規則改變了。回到4.1,讀取外部儲存許可權被引入作為寫外部儲存許可權的一個補充,而在那個時候並不是必須的。現在,這個許可權在4.4中被加強了,但是以一種不同尋常的方式。從訪問控制角度來看,外部儲存被分成兩個主要部分:1、App所在的目錄;2、其他地方。
讀取或者寫入資料到你的App所在的位置,不需要任何許可權。這基本可以適用任何通過Context裡面的方法可以訪問的目錄,比如getExternalFilesDir()
或getExternalCacheDir()
。如果只使用這些目錄,你甚至可以刪除你的應用程式中WRITE_EXTERNAL_STORAGE
許可權。
為了讀取外部儲存上其他資料,應用必須獲得READ_EXTERNAL_STAROAGE
或WRITE_EXTERNAL_STORAGE
許可權(兩者都需要被授權讀許可權)。這些可以通過Environment獲得的目錄,比如Environment裡面的getExternalStoragePublicDirectory()
或getExternalStorageDirectory()
函式。
更靈活的方法
與系統管理的計時器相關的週期性行為在預設情況下會變得更靈活,比如計時器中的AlarmManager
和SyncAdapter
。這樣做的目的是,允許系統儘可能批量處理事件並且減少裝置上的喚醒事件以節約電量。
之前的精確方法AlarmManger.set()
和AlarmManger.setRepeating()
,現在的行為更接近於AlarmManger.setInexactRepeating()
並且從屬於事件批處理。
從4.4開始,沒有任何方法可以建立一個重複的精確鬧鐘。如果你需要鬧鐘精確並且可重複,必須呼叫新的setExact()
方法並且在每個觸發事件中設定新的鬧鐘。
如果你使用SyncAdapter,由ContentResolver.addPeriodicSync()
提供的週期性同步行為在設計上支援一些彈性。這使得在4.4中增加了一個4%同步週期視窗(比如在一個小時的同步週期中佔用2.5分鐘)。另外,新的SyncRequest.Builder
API已經被允許一次或者有一些控制的彈性週期定期同步。比如SyncRequest.Builder.syncPeriodic()
執行基本的函式,比如addPeriodicSyn()
。可以支援時間間隔,這個時間間隔使得在同步時候介面卡可以被優化,變得安全且靈活。
因為這些功能是需要顯示設定targetSdkVersion為至少19 ,所以在這個版本之下的並沒有這些改變。但是一旦增加了這個版本必須特別注意並且測試你的應用的相容性。長期來說,儘可能支援靈活時鐘和同步將使你的應用尊重裝置的電池從而提升整理使用者體驗。
點陣圖重用
為了更進一步幫助應用程式減少記憶體佔用,android 4.4 建立了重用點陣圖分配的API。簡單來說點陣圖分配使得開發者很快達到堆限制。從Android 3.0 開始,使用BitmapFactory解碼資料時候就可以重用點陣圖例項(使用 BitmapFactory.Options 中的inBitmap ),但是約束相當的大。圖片必須恰好是同樣的尺寸和配置,並且只允許JPEG/PNG解碼。
在Android 4.4中,我們現在有Bitmap.reconfigure()
去修改和使得現有的例項去適應新的尺寸和畫素配置。BitmapFactory 已經被更新,之前在沒有這些約束的條件下通過重配置可以重用inBitmap
。
但是約束還是存在的。當點陣圖被建立,它有尺寸大小和配置,其中配置定義了分配的總位元組數。對於例項來說這種初始分配大小是不能被改變的。所以當我們多次重配置點陣圖時,每次改變都不可以讓需要的位元組數超過初始分配大小。
舉個例子,可以安全的重配置一個ARGB_8888 200*200
例項為ARGB_8888 100*100
,或者300*300 RGB_565
, 為所有的這些與初始分配相適應。如果試圖重配置到ARGB_8888 300*300
,這樣會丟擲異常。另外一點也很重要,當點陣圖被連線到檢視的時候,不能重配置。應該在這個元素被分離或者移出螢幕。
換句話說,如果你的應用程式可確定一個合適大小的單個例項,即使它可能比需要在任何給定時間的畫素較大,仍然可以減少記憶體使用。單個360KB點陣圖重用為300×300和200×200的影象(顯然不能同時顯示),是比兩個單獨的例項需要520KB(360KB+160KB)更好。
更智慧的集合類
為了加入SparseArray
、SparseIntArray
及其他同族行列,Android 4.4引入了一個新的記憶體高效的集合ArrayMap
。SparseArray
是通過減少必要的分配從而使用原語作為鍵來提高效能,ArrayMap
允許使用物件全鍵值對映,但遠遠比java.util.HashMap
中容量大小更具侵略性,物件分配隨著命中率和容量增加而減少。ArrayMap
大小隨著個體的刪除減少從而保持低記憶體,一些人們不能從java.util
中的期望。除了作為android.util
在API級別19的一部分;ArrayMap
也在支援庫的v19,所以你可以盡情使用,即使你不一定針對4.4。
Immersive模式
Android 4.4引入了一組新的佈局標誌可用於標記系統UI的可見性。從4.0開始,應用有隱藏狀態列和軟導航按鈕功能,並暫時使用View.SYSTEM_UI_FLAG_FULLSCREEN
和View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
標誌為“精益回”體驗,視訊內容會佔用整個顯示螢幕。然而,這種模式不是互動式的,而只要使用者點選螢幕上任意位置UI控制元件立刻返回(你的應用程式沒有收到的一個事件)。
為了增強這一點,在Android的4.4新增了View.SYSTEM_UI_FLAG_IMMERSIVE
和View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
。在與所提及的場景中使用這些標誌,可以在同一個系統中隱藏使用者介面,當與使用者的全屏應用程式內容進行互動時候還是保持這種方式。對於讓使用者無需導航控制元件,谷歌仍持謹慎態度。但是一個系統級的邊緣輕掃手勢允許他們在任何時候返回,使用者第一次體驗這種模式下,系統將疊加出現,迫使確認使用者瞭解如何讓UI控制元件回來。
下面是一個簡單的例子,內建一個檢視單擊處理方法通過需要的標誌組合(通過設定android:onClick
屬性)使得使用者進入Immersive模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
; html-script: false ] public void onToggleClick(View v) { //Hide the system UI. //The system will make the controls re-appear for us //when the user does an edge swipe from the top or bottom. v.setSystemUiVisibility( /* This flag tells Android not to shift * our layout when resizing the window to * hide/show the system elements */ View.SYSTEM_UI_FLAG_LAYOUT_STABLE /* This flag hides the system status bar. If * ACTION_BAR_OVERLAY is requested, it will hide * the ActionBar as well. */ | View.SYSTEM_UI_FLAG_FULLSCREEN /* This flag hides the on-screen controls */ | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION /* This flag tells the controls to stay hidden until * the user brings them back explicitly with a gesture */ | View.SYSTEM_UI_FLAG_IMMERSIVE); } |
之前,我提到的第二標誌製作身臨其境模式“粘性”。此標誌的行為跟第一種方式一樣,除了當在任何時候使用者回到系統的UI元素的時候,他們會自動隱藏一段時間後而非永久地留放回原處。應用程式可以通過清除粘標誌取消此模式。
WebView
在4.4中,WebView也有一些新的改變,現在是完全建立在谷歌的Chromium原始碼上。帶來的效能改進和來自HTML5和CSS3新功能,但它也意味著有一些行為上的差異需要開發者適應。
capturePicture()
被正式棄用,這是為了支援一個獲得WebView內容快照更標準的方法。比如手動觸發的onDraw()
可以繪製成點陣圖支援Canvas。
此外,evaluateJavascript()
提供了執行JavaScript的新方法,這新方法支援回撥。然而具有同樣功能的loadURL()
方法並沒有不被鼓勵使用或在文件中被棄用。
谷歌提供了一個很好的文件,包含所有可能會遇到遷移到新的WebView的問題細節。
App Ops迴歸
在4.3初現的App Ops功能現在還沒完全準備好。但是有一些已經還是在4.4 SDK中暴露了出來。
現在已經有AppOpsManager
, 這是一個系統服務用於執行應用程式可以沿著它當前的靜態許可權執行的操作。雖然還不清楚這個API最終將發揮什麼作用,但是我們可以看到AppOpsManger
所負責的一些操作型別。每個操作由一個OPSTR_
常量定義,並且在Android4.4中,他們都被用作處理使用者位置。
不管我們喜歡還是不喜歡,動態許可權執行的模型將會來臨。在隨後SDK的發展需要密切關注這些元素。
新執行時
自從誕生以來,Android一直依賴虛擬機器執行時,即是我們稱之為Dalvik,它被用來執行許多應用程式被編譯後生成的Java位元組碼。Dalvik是從自下而上構建的,提供給安卓Java執行時,使得安卓適合於作業系統需要的程式隔離和安全模式。
然而在Android的4.4中,我們可以看到Dalvik的生命週期是有限的,並且將很快由一個完全新的實現被稱為Android的執行時(ART)的替換。它還鮮為人知,超過我們收到的介紹範疇。主要的區別似乎是ART將在安裝時把Dex位元組碼編譯成本地指令,而不是Dalvik通過使用實時(JIT)編譯模型在執行時處理這些。與一些報導相反,似乎沒有被任何證據表明這種變化是在全是根據有關Java語言的許可或所有權問題。
ART編譯器似乎支援兩種模式:快速模式和便攜模式。快速模式是類似於JIT(在執行時編譯的程式碼),而便攜模式似乎使用LLVM關聯預編譯。這LLVM的連線可能最終解釋的幾個版本以前的AOSP的GDK專案神祕現象。
在Nexus 5的裝置上,ART被啟用從而可以被用來代替Dalvik,這樣就允許開發者來測試應用程式和提供有關可能突然出現的新的執行時環境中的任何問題的反饋。所有的開發人員都至少嘗試開發啟用了ART的應用程式並且報告任何有趣的發現給Google。
這個是我們關於KitKat開發者指南八篇中的一篇,本週晚些時候回來看看新的更新或者關注我們的twitter。