編輯:關於Android編程
Android5.0(Android Lollipop)是谷歌公司2014年10月發布的全新安卓系統,至今已經兩年多。然而由於國產手機對安卓ROM的深度定制或修改,以及手機廠商、芯片制造商、運營商之間錯綜復雜的關系,我們更新最新安卓版本往往需要1年左右時間的等待。2015年5月發布了Android6.0(Android Marshmallow),2016年8月發布了Android7.0(Android Nougat)。目前來說,用上6.0系統的手機都不太多,Android4.4和Android5.1版本占比重較高。但是,隨著時間推移,手機陸續都會升級到更高的系統版本,所以,提前學習到各版本的新特性,把一下好的效果添加到代碼中,並盡量做到向下兼容,應用才能擁有更好的體驗,面對升級過後的系統才能從容不迫。
從Android 5.0(Android Lollipop)開始,android迎來了扁平化時代,使用一種新的Material Design 設計風格,設計了全新的通知中心,開始支持多種設備。在性能上,放棄了之前一直使用的Dalvik虛擬機,改用ART模式,程序加載時間大幅提升。增加了Battery Saver模式來進行省電處理,以及全新的“最近應用程序”。
Android 6.0(Android Marshmallow)最大的亮點是為用戶提供了兩套相互獨立的解決方案,簡單的說,就是為每位用戶的每一個應用提供了兩套數據存儲方案。一套存儲工作資料,另一套存儲個人信息。另外Android M系統層面加入指紋識別,還加入了運行時權限,加入了App Standby(應用待機)、Doze(瞌睡)Exemptions(豁免)等模式來加強電源管理。
Android 7.0(Android Nougat),在性能處理有了巨大的提升,同時對文件數據加密,更加安全。 添加了分屏多任務,重新設計了通知,改進Doze休眠機制等。總而言之,Android N將更快,更高,更強。
提起Android5.0,就不得不說Material Design,扁平化的設計理念。新的視覺語言,在基本元素的處理上,借鑒了傳統的印刷設計,字體版式、網格系統、空間、比例、配色、圖像使用等這些基礎的平面設計規范。
之前的一些需要自定義的效果,現在都提供了系統級的支持,用起來更加方便了,而且android提供的效果看起來更加流暢。這裡篇幅較多,本著不重復造輪子的思想,筆者找了一片寫的很全面的Material Design的網站,圖文並茂,值得學習。
現在無論是智能手機、平板電腦、筆記本電腦、智能電視、汽車、智能手表甚至是各種家用電子產品,谷歌的Android系統已經可以在所有設備的屏幕上出現。而這一概念與微軟不謀而合,之前微軟也宣布將會把Windows 10打造成跨設備跨平台的統一系統,幫助自己走出困境。
谷歌在Android Lollipop中加入了全新風格的通知系統。改進後的通知系統會優先顯示對用戶來說比較重要的信息,而將不太緊急的內容隱藏起來。用戶只需要向下滑動就可以查看全部的通知內容。
新的通知系統另外一個很酷的新功能是在鎖屏界面也可以直接查看通知消息了。不僅如此,用戶還可以直接在鎖屏的情況下就行回復或進入應用。另外,如果在操作手機的過程中有電話進入,也不會進行全畫面切換,而是同樣以彈出通知的方式告知用戶。
新系統不僅在視覺效果上帶來了巨大的變化,Android Lollipop還在內部的性能上進行了飛躍。首先,新系統放棄了之前一直使用的Dalvik虛擬機,改用了ART模式,實現了真正的跨平台編譯,在ARM、X86、MIPS等,無處不在。
ART 虛擬機編譯器在內存占用及應用程序加載時間上進行了大幅提升,谷歌承諾所有性能都會比原來提升一倍。另外,對64位的支持也讓ART虛擬機如魚得水,開發者可以針對像ARM Cortex-A57這樣的64位架構核心開發應用程序。Android Lollipop支持更大的寄存器,支持新的指令集,提升了內存尋址空間,未來Android智能手機將支持4GB以上的內存。
Project Volta計劃增加了新工具可以讓開發者能夠更容易的找出為何自己的應用程序會對電量產生比較大的影響,同時確保在執行某型任務時將手機電量的影響降至最低。首先,Battery Historian可以列出手機電量消耗的詳細情況,幫助開發者識別電量消耗的原因或者是哪個硬件或任務對電池壽命的影響比較大;而Job Scheduler API則可以讓開發者更容易的選擇合適的時機觸發電量消耗比較高的任務,避免在低電量或未完成充電時更新應用程序。
上面是針對開發者的改進,而在用戶層面上,Android Lollipop增加了Battery Saver模式,這與三星和HTC上的超級省電模式有些類似。在低電量的時候系統會自動降低屏幕亮度、限制自動更換背景等功能。
除了界面風格設計的改變之外,新的最近應用界面還借鑒了Chrome浏覽器的理念,采用單獨的標簽展示方式。更重要的是,谷歌已經向開發者開放了API,所以第三方開發人員可以利用這個改進為特定的應用增加全新的功能。
現在個人識別解鎖還是一個比較新鮮的智能概念,當用戶的藍牙耳機連接到手機或平板電腦時,設備可以基於當前的位置或用戶的聲音自動解鎖。比如當特定的智能手表出現在Android設備的附近,那麼就會直接繞過鎖屏界面進行操作。而Android Lollipop也增加了這種針對特定特任識別解鎖的模式。換句話說,當設備沒有檢測到附近有可用的信任設備時,就會啟動安全模式防止未授權訪問。
另外,Android Lollipop還默認開啟了系統數據加密功能,並且通過SELinux執行應用程序,這就意味著對於惡意軟件來說,新系統變得更加安全。
谷歌表示Android Lollipop將擁有一個全新的特性,讓用戶通過一台設備就可以搞定所有的工作和生活娛樂活動。該特性首先將各種數據獨立保存,並且讓所有新數據的生成都有依據。
我們已經看到谷歌已經與三星加強了合作,包括三星的Knox安全系統同樣可以像Android Lollipop一樣將重要數據和其它數據分開保存。另外谷歌還允許向三星以外的Android設備提供支持。
谷歌將新系統的搜索功能重點放在了“重新發現”上,因此這意味著Google Search將會更好的意識到用戶正在做什麼。比如系統會根據用戶當前的位置自動過濾無關的搜索結果。
另外,當用戶在進行應用搜索時,可以直接展示相似或部分提示,並且進入特定的應用程序而無需將內容全部輸入。
Android Lollipop還增加了多個新的API支持、藍牙4.1、USB Audio外接音響及多人分享等功能。其中多人分享功能可以在用戶手機丟失的情況下,使用其它Lollipop設備登錄賬戶,從雲端下載聯系人、日歷等資料,並且不影響其它設備的內容。
Android 6.0引入了動態權限管理,將標記為危險的權限從安裝時權限(Install Time Permission)模型移動到運行時權限模型(Runtime Permissions):
安裝時權限模型(Android5.1以及更早):用戶在應用安裝和更新時,對危險權限授權。但是OEM和運行商預裝的應用將自動預授權。
運行時權限(Android6.0及以後):用戶在應用運行時,對應用授予危險權限。由應用決定何時去申請權限(例如,在應用啟動時或者用戶訪問某個特性時),但必須容許用戶來授予或者拒絕應用對特定權限組的訪問。OEM和運營商可以預裝應用,但是不能對權限進行預授權。
運行時權限提供給用戶關於應用所需權限更多的相關上下文和可視性,這也讓開發者幫助用戶更好的理解:為什麼應用需要所請求的權限,授權將有什麼樣的好處,拒絕將有何種不便。用戶可以通過設置中的菜單來撤銷應用的權限。
系統要求標記為危險(dangerous)的權限使用運行時權限模型。查看危險權限列表可以使用命令:adb shell pm list permissions -g -d 。
Android6.0並不改變正常權限的行為。正常權限指的是所有非危險(non-dangerous)權限,包括normal,system和signature 權限。正常權限風險較低,用於容許應用以最小風險來訪問隔離的應用級別的特性。在Android5.1和早期版本中,系統在安裝時自動將正常權限授予請求的應用,並不提示用戶
運行時權限模型適用於所有應用,包括預裝應用。應用軟件的要求包括:
運行時權限模型必須在所有運行Android6.0的設備上是一致的。這通過CTS來實施。
應用必須在運行時提示用戶進行授權。
帶有危險權限的預裝應用,必須符合API level 23,必須維護Android6.0的AOSP權限模型(例如,應用安裝的UI流程不應該脫離AOSP的packageInstaller的實現;用戶可以撤銷預裝應用的危險權限;等等)。
無界面的應用必須使用Activity來申請權限,或者與其他有相應權限的應用共享UID。
在設備從Android5.x升級到Android6.0之後,授予應用的權限仍然有效。但是用戶可以在任何時候撤銷這些權限。
說到指紋識別,很多用戶都會覺得現在的中高端安卓手機都支持,但事實上這些安卓手機的指紋識別都是各個廠商自行開發的並沒有系統底層的支持。Android 6.0則在系統層面加入指紋識別,能提供原生指紋識別API,這不但降低了廠商開發指紋識別模塊的成本,最重要的是原生指紋識別將會大大提升安卓手機的指紋識別支付安全性。
Android M加強了軟件間的關聯,谷歌在現場展示了一個例子,比如你的手機郵箱裡收到一封郵件,內文裡有以個Twitter鏈接,用戶點擊該鏈接可以直接跳轉到Twitter應用,而不再是網頁。
Chrome App Links這個就相當於在Web中使用Scheme來進行App的跳轉功能一樣,只不過這裡Chrome默認就支持了,用戶只需要搜索相關的關鍵詞,就可以直接顯示App,然後通過App Link直接啟動App。這個東西對用戶來說應該是一件非常好、方便的事情,但由於國內這些浏覽器的問題,不知道能否會兼容這個功能。
Android支付統一標准。新的M系統中集成了Android Pay。其特性在於簡潔、安全、可選性。Android Pay是一個開放性平台,用戶可以選擇谷歌的服務或者使用銀行的APP來使用它,Android Pay支持4.4以後系統設備,谷歌宣布Android Pay已經與美國三大運營商700多家商店達成合作,支付功能可以使用指紋來進行支付。
Android6.0引入了下列特性來延長電池使用時間:
App Standby(應用待機): 系統可以將未使用的應用置為AppStandby模式,臨時限制這些應用的網絡訪問,延遲同步和後台job
Doze(瞌睡): 如果用戶在某個時間期限內未主動使用設備(屏幕關閉、設備靜止),平台將進入深度睡眠狀態。因為該特性要求平台檢測靜止狀態,因此只有那些在Sensor HAL中實現了顯式移動檢測API的設備中才有效。
Exemptions(豁免): 預裝在設備上的系統應用和雲消息服務,默認通常被豁免。應用開發者可以要求其應用使用這種設定。用戶也可以在設置中來豁免某些應用。
對於不常用的應用的,AppStandby通過延遲後台網絡活動和任務來延長電池壽命。
生命周期
活動的應用不受AppStandby的影響。活動的含義是:
進程處於前台(Activity 或者前台服務,或者由另外一個Activity 或前台服務所使用),例如 notification listener,輔助服務,live 牆紙,等等。
供用戶查看的通知,可以是鎖屏通知或者通知圖標。
用戶顯式啟動的應用。
支持Doze功能的要求:
設備在Sensor HAL實現了significant motion detector (SMD) APIs 。
設備有某個雲消息服務,如 Google Cloud Messaging (GCM)。這使得設備可以知道何時從Doze中喚醒。
你可以在設置中,手動將某些應用從Doze和AppStandby中排除。
在之前,安卓系統雖然可以支持TF卡擴展,但TF卡擴展的容量只能當成外置存儲。雖然用戶可以把照片、音樂等內容放進去,但App不能安裝到其中。在安卓6.0中,當首次插入TF卡的時候,系統會詢問會將TF卡作為外置還是內置儲存。如果選擇作為內置存儲,系統則會對TF卡格式化並加密——注意,這會丟失數據!然後,TF卡的容量就和設備的內置存儲融合了。
一般來說,設備的內置存儲速度會比TF卡快上不少,穩定性也更高,因此如果不是容量特別緊張,並不建議把TF當成內置儲存植入。同時,市面上支持TF卡擴展的安卓設備也越來越少,安卓6.0的這個新特性也許會遭到冷遇。
Android7.0提供新功能以提升性能、生產效率和安全性。
關於Android N的性能改進,Android N建立了先進的圖形處理Vulkan系統,能少的減少對CPU的占用。與此同時,Android N加入了JIT編譯器,安裝程序快了75%,所占空間減少了50%。
在安全性上,Android N加入了全新安全性能,其中包括基於文件的數據加密。谷歌移動版Chrome能識別惡意網站。
Android N可以進行無縫更新,與Chromebook一樣,用戶將不再需要下載安裝,也不再需要進行重啟。
在效率提升上,Android N可以自動關閉用戶較長時間未使用的應用程序。在通知上新增了直接回復功能,並支持一鍵全部清除功能
進入後台多任務管理頁面,然後按住其中一個卡片,然後向上拖動至頂部即可開啟分屏多任務,支持上下分欄和左右分欄,允許拖動中間的分割線調整兩個APP所占的比例。
在Android 7.0中,下拉打開通知欄頂部即可顯示5個用戶常用的快捷開關,支持單擊開關以及長按進入對應設置。如果繼續下拉通知欄即可顯示全部快捷開關,此外在快捷開關頁右下角也會顯示一個“編輯”按鈕,點擊之後即可自定義添加/刪除快捷開關,或拖動進行排序。
加入了全新的API,支持第三方應用通知的快捷操作和回復,例如來電會以橫幅方式在屏幕頂部出現,提供接聽/掛斷兩個按鈕;信息/社交類應用通知,還可以直接打開鍵盤,在輸入欄裡進行快捷回復。
Android7.0會將同一應用的多條通知提示消息歸攏為一項,點擊該項即可展開此前的全部通知,允許用戶對每個通知執行單獨操作。
Android7.0中重新加入了夜間深色主題模式,該功能依然需要在系統調諧器中開啟,從頂部下劃打開快捷設置頁,然後長按其中的設置圖標,齒輪旋轉10秒鐘左右即可提示已開啟系統調諧器,之後用戶在設置中即可找到“系統調諧器”設置項。點開其中的“色彩和外觀”,即可找到夜間模式,開啟後即可使用全局的深色主題模式,同時亮度和色彩也會進行一定的調整,該功能可以基於時間或地理位置自動開啟。另外,系統調諧器中也提供了RGB紅綠藍三色調節滑動條,允許用戶手動精細調節,例如減少藍色或增加紅色以提供類似護眼模式的效果。
新增的流量保護模式不僅可以禁止應用在後台使用流量,還會進一步減少該應用在前台時的流量使用。推測其有可能使用了類似Chrome浏覽器的數據壓縮技術。此外,谷歌還擴展了ConnectivityManager API的能力,使得應用可以檢測系統是否開啟了流量保護模式,或者檢測自己是否在白名單中。Android7.0允許用戶單獨針對每個應用,選擇是否開啟數據保護模式。
Android7.0啟用了全新的設置樣式,首先每個分類下各個子項之間的分割線消失了,只保留分類之間的分割線。全新的設置菜單還提供了一個綠色的頂欄,允許用戶通過後方的下拉箭頭,快速設定勿擾模式等。除了勿擾模式外,頂欄菜單還可以顯示諸多其他的設置狀態,例如數據流量的使用情況,自動亮度是否開啟等。谷歌也在安卓7.0的設置中加入了漢堡菜單,在二級設置界面中的左上角,你就會看到這個漢堡菜單,點擊後即可看到所有設置項,方便用戶快速跳轉。
谷歌在Android7.0中對Doze休眠機制做了進一步的優化,在此前的Android6.0中,Doze深度休眠機制對於改善安卓的續航提供了巨大的作用。而在Android67.0中,谷歌對Doze進行了更多的優化,休眠機制的使用規則和場景有所擴展,例如只要手動在後台刪掉應用卡片,關屏後該應用就會被很快深度休眠。
Android7.0將電話攔截功能變成了一個系統級功能。其它應用可以調用這個攔截名單,但只有個別應用可以寫入,包括撥號應用、默認的短信應用等。被攔截號碼將不會出現在來電記錄中,也不會出現通知。另外用戶也可以通過賬戶體系備份和恢復這個攔截名單,以便快速導入其它設備或賬號。
雙擊菜單鍵,就能自動切換到上一個應用。此外,如果你不停地點擊菜單鍵的話,就會在所有應用中不間斷地輪換,應用窗口會自動放大,頂部還會出現倒計時條,停止點擊且倒計時結束後,當前應用會自動放大並返回到前台。
各個新版本的Android系統除了提供了諸多新特性和功能外,還對系統和API行為做出了各種變更。以下重點介紹您應該了解並在開發應用時加以考慮的一些主要變更。(其中某些變更與上面提到的新特性有重復的地方,姑且聽之)
API級別:21
大多數 Android 應用無需任何更改就可以在 ART 下工作。不過,部分適合 Dalvik 的技術並不適用於 ART。如需了解有關最重要問題的信息,請參閱在 Android Runtime (ART) 上驗證應用行為。如存在以下情況,應特別注意:
您的應用使用 Java 原生接口 (JNI) 運行 C/C++ 代碼。 您使用生成非標准代碼的開發工具(例如,一些代碼混淆工具)。 您使用與壓縮垃圾回收不兼容的技術
如果您當前使用 Ringtone、MediaPlayer 或 Vibrator 類向通知中添加聲音和振動,則移除此代碼,以便系統可以在“優先”模式中正確顯示通知。取而代之的是,使用 Notification.Builder 方法添加聲音和振動。
將設備設為 RINGER_MODE_SILENT 可使設備進入新的優先模式。如果您將設備設為 RINGER_MODE_NORMAL 或 RINGER_MODE_VIBRATE,則設備將退出優先模式。
以前,Android 使用 STREAM_MUSIC 作為主流式傳輸來控制平板電腦設備上的音量。在 Android 5.0 中,手機和平板電腦設備的主音量流式傳輸現已合並,由 STREAM_RING 或 STREAM_NOTIFICATION 進行控制。
默認情況下,在 Android 5.0 中,通知現在顯示在用戶的鎖定屏幕上。用戶可以選擇保護敏感信息不被公開,在此情況下,系統會自動刪減通知顯示的文本。要自定義此刪減的通知,請使用 setPublicVersion()。
如果通知不包含個人信息,或者您想允許媒體播放控件顯示在通知上,則調用 setVisibility() 方法並將通知的可見性級別設為 VISIBILITY_PUBLIC。
現在,當設備處於活動狀態時(即,設備未鎖定且其屏幕已打開),通知可以顯示在小型浮動窗口中(也稱為“浮動通知”)。這些通知看上去類似於精簡版的通知,只是浮動通知還顯示操作按鈕。用戶可以在不離開當前應用的情況下處理或清除浮動通知。
可能觸發浮動通知的條件示例包括:
用戶的 Activity 處於全屏模式中(應用使用 fullScreenIntent)
通知具有較高的優先級並使用鈴聲或振動
如果您的應用在以上任何情形下實現通知,請確保系統正確顯示浮動通知。
為提升用戶隱私的安全性,現已棄用 ActivityManager.getRecentTasks() 方法。對於向後兼容性,此方法仍會返回它的一小部分數據,包括調用應用自己的任務和可能的一些其他非敏感任務(如首頁)。如果您的應用使用此方法檢索它自己的任務,則改用 getAppTasks() 檢索該信息。
Context.bindService() 方法現在需要顯式 Intent,如果提供隱式 intent,將引發異常。為確保應用的安全性,請使用顯式 intent 啟動或綁定 Service,且不要為服務聲明 intent 過濾器。
Android 5.0 更改了應用的默認行為。
如果您的應用是面向 API 級別 21 或更高級別:
默認情況下,系統會阻止混合內容和第三方 Cookie。要允許混合內容和第三方 Cookie,請分別使用 setMixedContentMode() 和 setAcceptThirdPartyCookies() 方法。
系統現在可以智能地選擇要繪制的 HTML 文檔部分。這個新的默認行為有助於減少內存占用和提升性能。如果您要一次渲染整個文檔,可通過調用 enableSlowWholeDocumentDraw() 停用此優化。
如果您的應用是面向低於 21 的 API 級別:系統允許混合內容和第三方 Cookie,並始終一次渲染整個文檔。
API級別:23
對於以 Android 6.0(API 級別 23)或更高版本為目標平台的應用,請務必在運行時檢查和請求權限。要確定您的應用是否已被授予權限,請調用新增的 checkSelfPermission() 方法。要請求權限,請調用新增的 requestPermissions() 方法。即使您的應用並不以 Android 6.0(API 級別 23)為目標平台,您也應該在新權限模式下測試您的應用。
Android 6.0 版移除了對 Apache HTTP 客戶端的支持。如果您的應用使用該客戶端,並以 Android 2.3(API 級別 9)或更高版本為目標平台,請改用 HttpURLConnection 類。此 API 效率更高,因為它可以通過透明壓縮和響應緩存減少網絡使用,並可最大限度降低耗電量。要繼續使用 Apache HTTP API,您必須先在 build.gradle 文件中聲明以下編譯時依賴項:
android { useLibrary 'org.apache.http.legacy' }
Android 正在從使用 OpenSSL 庫轉向使用 BoringSSL 庫。如果您要在應用中使用 Android NDK,請勿鏈接到並非 NDK API 組成部分的加密庫,如 libcrypto.so 和 libssl.so。這些庫並非公共 API,可能會在不同版本和設備上毫無征兆地發生變化或出現故障。此外,您還可能讓自己暴露在安全漏洞的風險之下。請改為修改原生代碼,以通過 JNI 調用 Java 加密 API,或靜態鏈接到您選擇的加密庫。
此版本移除了 Notification.setLatestEventInfo() 方法。請改用 Notification.Builder 類來構建通知。要重復更新通知,請重復使用 Notification.Builder 實例。調用 build() 方法可獲取更新後的 Notification 實例。
adb shell dumpsys notification 命令不再打印輸出您的通知文本。請改用 adb shell dumpsys notification --noredact 命令打印輸出 notification 對象中的文本。
不再支持通過 AudioManager 類直接設置音量或將特定音頻流靜音。setStreamSolo() 方法已棄用,您應該改為調用 requestAudioFocus() 方法。類似地,setStreamMute() 方法也已棄用,請改為調用 adjustStreamVolume() 方法並傳入方向值 ADJUST_MUTE 或 ADJUST_UNMUTE。
在此版本中,相機服務中共享資源的訪問模式已從之前的“先到先得”訪問模式更改為高優先級進程優先的訪問模式。對服務行為的變更包括:
根據客戶端應用進程的“優先級”授予對相機子系統資源的訪問權,包括打開和配置相機設備。帶有對用戶可見 Activity 或前台Activity 的應用進程一般會被授予較高的優先級,從而使相機資源的獲取和使用更加可靠;
當高優先級的應用嘗試使用相機時,系統可能會“驅逐”正在使用相機客戶端的低優先級應用。在已棄用的 Camera API 中,這會導致系統為被驅逐的客戶端調用 onError()。在 Camera2 API 中,這會導致系統為被驅逐的客戶端調用onDisconnected();
在配備相應相機硬件的設備上,不同的應用進程可同時獨立打開和使用不同的相機設備。但現在,如果在多進程用例中同時訪問相機會造成任何打開的相機設備的性能或能力嚴重下降,相機服務會檢測到這種情況並禁止同時訪問。即使並沒有其他應用直接嘗試訪問同一相機設備,此變更也可能導致低優先級客戶端被“驅逐”。
更改當前用戶會導致之前用戶帳戶擁有的應用內活動相機客戶端被驅逐。對相機的訪問僅限於訪問當前設備用戶擁有的用戶個人資料。舉例來說,這意味著,當用戶切換到其他帳戶後,“來賓”帳戶實際上無法讓使用相機子系統的進程保持運行狀態
API級別:24
Android 7.0 包括旨在延長設備電池壽命和減少 RAM 使用的系統行為變更。這些變更可能會影響您的應用訪問系統資源,以及您的應用通過特定隱式 intent 與其他應用交互的方式。
Android 7.0 移除了三項隱式廣播,以幫助優化內存使用和電量消耗。此項變更很有必要,因為隱式廣播會在後台頻繁啟動已注冊偵聽這些廣播的應用。刪除這些廣播可以顯著提升設備性能和用戶體驗。
移動設備會經歷頻繁的連接變更,例如在 WLAN 和移動數據之間切換時。目前,可以通過在應用清單中注冊一個接收器來偵聽隱式 CONNECTIVITY_ACTION 廣播,讓應用能夠監控這些變更。由於很多應用會注冊接收此廣播,因此單次網絡切換即會導致所有應用被喚醒並同時處理此廣播。
同理,在之前版本的 Android 中,應用可以注冊接收來自其他應用(例如相機)的隱式 ACTION_NEW_PICTURE 和 ACTION_NEW_VIDEO 廣播。當用戶使用相機應用拍攝照片時,這些應用即會被喚醒以處理廣播。
為緩解這些問題,Android 7.0 應用了以下優化措施:
面向 Android 7.0 開發的應用不會收到 CONNECTIVITY_ACTION 廣播,即使它們已有清單條目來請求接受這些事件的通知。在前台運行的應用如果使用 BroadcastReceiver 請求接收通知,則仍可以在主線程中偵聽 CONNECTIVITY_CHANGE。
應用無法發送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項優化會影響所有應用,而不僅僅是面向 Android 7.0 的應用。
如果您的應用使用任何 intent,您仍需要盡快移除它們的依賴關系,以正確適配 Android 7.0 設備。Android 框架提供多個解決方案來緩解對這些隱式廣播的需求。例如,JobScheduler API 提供了一個穩健可靠的機制來安排滿足指定條件(例如連入無限流量網絡)時所執行的網絡操作。您甚至可以使用 JobScheduler 來適應內容提供程序變化。
為了提高私有文件的安全性,面向 Android 7.0 或更高版本的應用私有目錄被限制訪問 (0700)。此設置可防止私有文件的元數據洩漏,如它們的大小或存在性。此權限更改有多重副作用:
1.私有文件的文件權限不應再由所有者放寬,為使用 MODE_WORLD_READABLE 和/或 MODE_WORLD_WRITEABLE 而進行的此類嘗試將觸發 SecurityException。
注:迄今為止,這種限制尚不能完全執行。應用仍可能使用原生 API 或 File API 來修改它們的私有目錄權限。但是,我們強烈反對放寬私有目錄的權限。2.傳遞軟件包網域外的 file:// URI 可能給接收器留下無法訪問的路徑。因此,嘗試傳遞 file:// URI 會觸發 FileUriExposedException。分享私有文件內容的推薦方法是使用 FileProvider。
3.DownloadManager 不再按文件名分享私人存儲的文件。舊版應用在訪問 COLUMN_LOCAL_FILENAME 時可能出現無法訪問的路徑。面向 Android 7.0 或更高版本的應用在嘗試訪問 COLUMN_LOCAL_FILENAME 時會觸發 SecurityException。通過使用 DownloadManager.Request.setDestinationInExternalFilesDir() 或DownloadManager.Request.setDestinationInExternalPublicDir() 將下載位置設置為公共位置的舊版應用仍可以訪問 COLUMN_LOCAL_FILENAME 中的路徑,但是我們強烈反對使用這種方法。對於由 DownloadManager 公開的文件,首選的訪問方式是使用ContentResolver.openFileDescriptor() 。
對於面向 Android 7.0 的應用,Android 框架執行的 StrictMode API 政策禁止在您的應用外部公開 file:// URI。如果一項包含文件 URI 的 intent 離開您的應用,則應用出現故障,並出現 FileUriExposedException 異常。
要在應用間共享文件,您應發送一項 content:// URI,並授予 URI 臨時訪問權限。進行此授權的最簡單方式是使用 FileProvider 類。
Android 7.0 支持用戶設置顯示尺寸,以放大或縮小屏幕上的所有元素,從而提升設備對視力不佳用戶的可訪問性。用戶無法將屏幕縮放至低於最小屏幕寬度 sw320dp,該寬度是 Nexus 4 的寬度,也是常規中等大小手機的寬度。
當設備密度發生更改時,系統會以如下方式通知正在運行的應用:
如果是面向 API 級別 23 或更低版本系統的應用,系統會自動終止其所有後台進程。這意味著如果用戶切換離開此類應用,轉而打開 Settings 屏幕並更改 Display size 設置,則系統會像處理內存不足的情況一樣終止該應用。如果應用具有任何前台進程,則系統會如處理運行時更改中所述將配置變更通知給這些進程,就像對待設備屏幕方向變更一樣。
如果是面向 Android 7.0 的應用,則其所有進程(前台和後台)都會收到有關配置變更的通知,如處理運行時更改中所述。
大多數應用並不需要進行任何更改即可支持此功能,不過前提是這些應用遵循 Android 最佳做法。具體要檢查的事項:
1.在屏幕寬度為 sw320dp 的設備上測試您的應用,並確保其充分運行。
2.當設備配置發生變更時,更新任何與密度相關的緩存信息,例如緩存位圖或從網絡加載的資源。當應用從暫停狀態恢復運行時,檢查配置變更。
注:如果您要緩存與配置相關的數據,則最好也包括相關元數據,例如該數據對應的屏幕尺寸或像素密度。保存這些元數據便於您在配置變更後決定是否需要刷新緩存數據。3.避免用像素單位指定尺寸,因為像素不會隨屏幕密度縮放。應改為使用與密度無關像素 (dp) 單位指定尺寸。
為幫助您識別加載私有庫的問題,logcat 可能會生成一個警告或運行時錯誤。例如,如果您的應用面向 API 級別 23 或更低級別,並在運行 Android 7.0 的設備上嘗試訪問私有庫,您可能會看到一個類似於下面所示的警告:
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 警告通知您哪個庫正在嘗試訪問私有平台 API,但不會導致您的應用崩潰。但是,如果應用面向 API 級別 24 或更高級別,logcat 會生成以下運行時錯誤,您的應用可能會崩潰:
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)
如果您的應用使用動態鏈接到私有平台 API 的第三方庫,您可能也會看到上述 logcat 輸出。利用 Android 7.0DK 中的 readelf 工具,您可以通過運行以下命令生成給定 .so 文件的所有動態鏈接的共享庫列表:
aarch64-linux-android-readelf -dW libMyLibrary.so
⑴如果一個應用在 Android 7.0 上運行,但卻是針對更低 API 級別開發的,那麼在用戶更改顯示尺寸時,系統將終止此應用進程。應用必須能夠妥善處理此情景。否則,當用戶從最近使用記錄中恢復運行應用時,應用將會出現崩潰現象。
您應測試應用以確保不會發生此行為。要進行此測試,您可以通過 DDMS 手動終止應用,以造成相同的崩潰現象。
在密度發生更改時,系統不會自動終止面向 N 及更高版本的應用;不過,這些應用仍可能對配置變更做出不良響應。
⑵Android 7.0 上的應用應能夠妥善處理配置變更,並且在後續啟動時不會出現崩潰現象。您可以通過更改字體大小 (Setting >Display > Font size) 並隨後從最近使用記錄中恢復運行應用,來驗證應用行為。
⑶由於之前的 Android 版本中的一項錯誤,系統未能將對主線程上的一個 TCP 套接字的寫入操作舉報為違反嚴格模式。Android 7.0 修復了此錯誤。呈現出這種行為的應用現在會引發 android.os.NetworkOnMainThreadException 。一般情況下,我們不建議在主線程上執行網絡操作,因為這些操作通常會出現可能導致 ANR 和卡頓的高尾延遲。
⑷Debug.startMethodTracing() 方法系列現在默認在您的共享存儲空間上的軟件包特定目錄中存儲輸出,而非 SD 卡根目錄。這意味著應用不再需要請求 WRITE_EXTERNAL_STORAGE 權限來使用這些 API 。
⑸許多平台 API 現在開始檢查在 Binder 事務間發送的大負載,系統現在會將 TransactionTooLargeExceptions 作為 RuntimeExceptions 再次引發,而不再只是默默記錄或抑制它們。一個常見例子是在 Activity.onSaveInstanceState() 上存儲過多數據,導致 ActivityThread.StopInfo 在您的應用面向 Android 7.0 時引發 RuntimeException。
⑹如果應用向 View 發布 Runnable 任務,並且 View 未附加到窗口,系統會用 View 為 Runnable 任務排隊;在 View 附加到窗口之前,不會執行 Runnable 任務。此行為會修復以下錯誤:
如果一項應用是從並非預期窗口 UI 線程的其他線程發布到 View,則 Runnable 可能會因此運行錯誤的線程。
如果 Runnable 任務是從並非環路線程的其他線程發布,則應用可能會曝光 Runnable 任務。
⑺如果 Android 7.0 上一項有 DELETE_PACKAGES 權限的應用嘗試刪除一個軟件包,但另一項應用已經安裝了這個軟件包,則系統需要用戶進行確認。在這種情況下,應用在調用 PackageInstaller.uninstall() 時預計的返回狀態應為 STATUS_PENDING_USER_ACTION 。
⑻名為 Crypto 的 JCA 提供程序已棄用,因為它僅有的 SHA1PRNG 算法為弱加密。應用無法再使用 SHA1PRNG(不安全地)派生密鑰,因為不再提供此提供程序。
對於Android新特性的使用,不可能一蹴而就,但是手機在不斷升級,Andriod6.0,7.0也會成為安卓陣營中的主力,Android應用也需要陸續的把這些新特性或者新API裡的方法用上,做到向下兼容,緊跟時代潮流。
在實際過程中需要各方面協調。拿Android 5.0上引入的Material Design來說,從設計上講,設計人員、美工和開發人員都需要了解一下Material Design設計語言,相互協調,統一風格;從開發上講,需要根據新特性和api來優化或者適當重構代碼;另外有必要重新編碼基類和工具類,比如notifications,toolbars,toast,cards,dialogs等來適應新的安卓風格。
通過前面的幾篇博客,我們解決了如何啟動一個並沒有在ActivityManifest.xml中聲明的activity。但是有很多細心的讀者私信我說,我們所有的例子裡,插件都
前言React Native已經出現很久了,有很多應用也在進行嘗試,前面我們也講述了怎麼創建React Native工程以及怎麼搭建原生語言與js的開發環境。但是在實際應
最近寫博客的時間,都是在晚上圖書館學習回到宿捨後,大概是11點半開始寫,寫著寫著就1點多了,這還是我積累的比較充分了的情況下的,然後自己要看一遍再睡覺。第二天早上還要審稿
之前備份短信的時候生成xml都是手動拼寫的,有一個問題:當短信裡面存在這樣的標簽的時候,最後結果就不是完整的xml文件,顯然出錯。但是,今天使用序列化器的方式,就能有效的