掌握Android O 行為變更指南,參與互動贏收藏版 Android 公仔!

2021-01-10 搜狐網

  Android O 除了提供諸多新特性和功能外,還對系統和 API 行為做出了各種變更。本文重點介紹您應該了解並在開發應用時加以考慮的一些主要變更。

  其中大部分變更會影響所有應用,而不論應用針對的是何種版本的 Android。不過,有幾項變更僅影響針對 Android O 的應用。為清楚起見,本頁面分為兩個部分:針對所有 API 級別的應用和針對 Android O 的應用。

  針對所有 API 級別的應用

  這些行為變更適用於在 Android O 平臺上運行的所有應用,無論這些應用是針對哪個 API 級別構建。所有開發者都應查看這些變更,並修改其應用以正確支持這些變更(如果適用)。

  網絡連接和 HTTP(S) 連接

  Android O 對網絡連接和 HTTP(S) 連接行為做出了以下變更:

無正文的 OPTIONS 請求具有 Content-Length: 0標頭。之前,這些請求沒有 Content-Length標頭。

HttpURLConnection 在包含斜線的主機或頒發機構名稱後面附加一條斜線,使包含空路徑的網址規範化。例如,它將 http://example.com轉化為 http://example.com/ 。

通過 ProxySelector.setDefault ( ) 設置的自定義代理選擇器僅針對所請求的網址(架構、主機和埠)。因此,僅可根據這些值選擇代理。傳遞至自定義代理選擇器的網址不包含所請求的網址的路徑、查詢參數或片段。

URI 不能包含空白標籤。

之前,平臺支持一種權宜方法,即允許主機名稱中包含空白標籤,但這是對 URI 的非法使用。此權宜方法只是為了確保與舊版 libcore 兼容。開發者如果對 API 使用不當,將會看到一條 ADB 消息:「URI example..com 的主機名包含空白標籤。此格式不正確,將不被未來的 Android 版本所接受。」Android O 廢除了此權宜方法;系統對格式錯誤的 URI 會返回 null。

Android O 在實現 HttpsURLConnection 時不會執行不安全的 TLS/SSL 協議版本回退。

對隧道 HTTP(S) 連接處理進行了如下變更:

在通過連接建立隧道 HTTP(S) 連接時,系統會在 Host 行中正確放置埠號 (:443) 並將此信息發送至中間伺服器。之前,埠號僅出現在 CONNECT 行中

系統不再將隧道連接請求中的 user-agent 和 proxy-authorization 標頭髮送至代理伺服器。

在建立隧道時,系統不再將隧道 Http(s)URLConnection 中的 proxy-authorization 標頭髮送至代理。相反,由系統生成 proxy-authorization 標頭,在代理響應初始請求發送 HTTP 407 後將其發送至此代理。

同樣地,系統不再將 user-agent 標頭由隧道連接請求複製到建立隧道的代理請求。相反,庫為此請求生成 user-agent 標頭。

如果之前執行的 connect ( ) 函數失敗,send( java.net.DatagramPacket )函數將會引發 SocketException:

在回退到 TCP Echo 協議之前,InetAddress.isReachable ( ) 會嘗試執行 ICMP:

  集合的處理

  現在,AbstractCollection.removeAll ( )和 AbstractCollection.retainAll ( ) 始終引發 NullPointerException;之前,當集合為空時不會引發 NullPointerException。此項變更使行為符合文檔要求。

  記錄未捕獲的異常

  如果某個應用安裝的 Thread.UncaughtExceptionHandler 未移交給默認的 Thread.UncaughtExceptionHandler,則當出現未捕獲的異常時,系統不會終止應用。從 Android O 開始,在此情況下系統將記錄異常堆棧跟蹤情況;在之前的平臺版本中,系統不會記錄異常堆棧跟蹤情況。

  我們建議,自定義 Thread.UncaughtExceptionHandler實現始終移交給默認處理程序處理;遵循此建議的應用不受 Android O 此項變更的影響。

  輸入和導航

  隨著 Android 應用出現在 Chrome 作業系統和平板電腦等其他大尺寸設備上,我們看到,用戶在 Android 應用中又重新開始使用鍵盤導航。在 Android O 中,我們又再次使用鍵盤作為導航輸入設備,從而為基於箭頭鍵和 Tab 鍵的導航構建了一種更可靠並且可預測的模型。

  尤其要指出的是,我們對元素焦點行為做出以下變更:

現在,如果您沒有為 View對象(前景或背景圖片)定義任何焦點狀態顏色,框架會為 View設置默認的焦點突出顯示顏色。此焦點突出顯示標誌是基於操作組件主題背景的漣漪圖片。

如果您不希望 View對象在接收焦點時使用此默認突出顯示標誌,請在包含 View的布局 XML 文件中將 android:defaultFocusHighlightEnabled屬性設置為 false ,或者將 false傳遞至應用界面邏輯中的 setDefaultFocusHighlightEnabled ( )。

要測試鍵盤輸入對界面元素焦點有何影響,您可以啟用 Drawing > Show layout bounds開發者選項。在 Android O 中,此選項在當前具有焦點的元素上顯示一個 「X」 圖標。

  另外,Android O 中的所有工具欄元素自動組成鍵盤導航鍵區,用戶可以更加輕鬆地導航進入和離開每個作為一個整體的工具欄。

  如需詳細了解如何在您的應用中改善對鍵盤導航的支持,請閱讀以下連結中的支持鍵盤導航指南。

  (https://developer.android.google.cn/training/keyboard-input/navigation.html)

  安全性

  Android O 包含以下與安全性有關的變更:

此平臺不再支持 SSLv3

Android O 將使用安全計算 (SECCOMP) 過濾器來過濾所有應用。允許的系統調用列表僅限於通過 bionic 公開的系統調用。此外,還提供了其他幾個後向兼容的系統調用,但我們不建議使用這些系統調用。

在與未正確實現 TLS 協議版本協商的伺服器建立 HTTPS 連接時,HttpsURLConnection不再嘗試回退到之前的 TLS 協議版本並重試的權宜方法。

現在,您的應用的 WebView對象將在多進程模式下運行。網頁內容在獨立的進程中處理,此進程與包含應用的進程相隔離,以提高安全性。

您無法再假定 APK 駐留在名稱以 -1 或 -2 結尾的目錄中。應用應使用 sourceDir 獲取此目錄,而不能直接使用目錄格式。

  有關提升應用安全性的其他準則,請參閱以下連結中的面向 Android 開發者的安全性。

  (https://developer.android.google.cn/topic/security/index.html)

  後臺執行限制

  Android O 為提高電池續航時間而引入的變更之一是,當您的應用進入已緩存狀態時,如果沒有活動的組件,系統將解除應用具有的所有喚醒鎖。

  此外,為提高設備性能,系統會限制未在前臺運行的應用的某些行為。具體而言:

  Android O 還對特定函數做出了以下變更:

如果針對 Android O 的應用嘗試在不允許其創建後臺服務的情況下使用 startService ( )函數,則該函數將引發一個 IllegalStateException。

新的 Context.startForegroundService ( )函數將啟動一個前臺服務。現在,即使應用在後臺運行,系統也允許其調用 Context.startForegroundService ( ) 。不過,應用必須在創建服務後的五秒內調用該服務的 startForeground ( )函數。

  如需了解詳細信息,請參閱以下連結中的後臺執行限制。

  (https://developer.android.google.cn/preview/features/background.html)

  隱私性

  Android O 對平臺做出了以下與隱私性有關的變更:

現在,平臺改變了標識符的處理方式:

對於在 OTA 之前安裝到某個版本 Android O(API 級別 26)的應用,除非在 OTA 後卸載並重新安裝,否則 ANDROID_ID的值將保持不變。要在 OTA 後在卸載期間保留值,開發者可以使用密鑰/值備份關聯舊值和新值。

對於安裝在運行 Android O 的設備上的應用,ANDROID_ID的值現在將根據應用籤署密鑰和用戶確定作用域。應用籤署密鑰、用戶和設備的每個組合都具有唯一的 ANDROID_ID值。因此,在相同設備上運行但具有不同籤署密鑰的應用將不會再看到相同的 Android ID(即使對於同一用戶來說,也是如此)。

只要籤署密鑰相同(並且應用未在 OTA 之前安裝到某個版本的 O),ANDROID_ID的值在軟體包卸載或重新安裝時就不會發生變化。

即使系統更新導致軟體包籤署密鑰發生變化,ANDROID_ID的值也不會變化。

要藉助一個簡單的標準系統實現應用獲利,請使用廣告 ID。廣告 ID 是 Google Play 服務針對廣告服務提供的唯一 ID,此 ID 可由用戶重置。

查詢 net.hostname系統屬性返回的結果為空。

  針對 Android O 的應用

  這些行為變更專門應用於針對 O 平臺或更高平臺版本的應用。針對 Android O 或更高平臺版本進行編譯,或將 targetSdkVersion設為 Android O 或更高版本的應用開發者必須修改其應用以正確支持這些行為(如果適用)。

  內容變更通知

  Android O 更改了 ContentResolver.notifyChange ( ) 和 registerContentObserver ( Uri, boolean, ContentObserver )在針對 Android O 的應用中的行為方式。

  現在,這些 API 需要在所有 URI 中為頒發機構定義一個有效的 ContentProvider。使用相關權限定義一個有效的 ContentProvider可幫助您的應用防範來自惡意應用的內容變更,並防止將可能的私密數據洩露給惡意應用。

  視圖焦點

  可點擊的 View對象現在默認也可以成為焦點。如果您希望 View對象可點擊但不可成為焦點,請在包含 View的布局 XML 文件中將 android:focusable屬性設置為 false,或者將 false傳遞至應用界面邏輯中的 setFocusable ( )。

  權限

  在 Android O 之前,如果應用在運行時請求權限並且被授予該權限,系統會錯誤地將屬於同一權限組並且在清單中註冊的其他權限也一起授予應用。

  對於針對 Android O 的應用,此行為已被糾正。系統只會授予應用明確請求的權限。然而,一旦用戶為應用授予某個權限,則所有後續對該權限組中權限的請求都將被自動批准。

  例如:

  假設某個應用在其清單中列出 READ_EXTERNAL_STORAGE和 WRITE_EXTERNAL_STORAGE 。應用請求 READ_EXTERNAL_STORAGE ,並且用戶授予了該權限。

  如果該應用針對的是 API 級別 24 或更低級別,系統還會同時授予 WRITE_EXTERNAL_STORAGE ,因為該權限也屬於同一 STORAGE權限組並且也在清單中註冊過。

  如果該應用針對的是 Android O,則系統此時僅會授予 READ_EXTERNAL_STORAGE ;不過,如果該應用後來又請求 WRITE_EXTERNAL_STORAGE ,則系統會立即授予該權限,而不會提示用戶。

  集合的處理

  在 Android O 中,Collections.sort ( )是在List.sort ( ) 的基礎上實現的。在 Android 7.x(API 級別 24 和 25)中,則恰恰相反。在過去,List.sort ( )的默認實現會調用Collections.sort ( )。

  此項變更使Collections.sort ( )可以利用優化的 List.sort ( )實現,但具有以下限制:

List.sort ( )的實現不能調用Collections.sort ( ),因為這會導致堆棧因無限遞歸而溢出。相反,如果您需要 List 實現的默認行為,應避免重寫 sort()。

  如果父類以不適當的方法實現sort ( ),通常最好使用在List.toArray ( )、Arrays.sort ( )和ListIterator.set ( )的基礎上構建的實現重寫List.sort ( ) 。

  例如:

  @Override

  publicvoidsort(Comparator<?superE>c){

  Object[]elements =toArray();

  Arrays.sort(elements,c);

  ListIterator<E>iterator =(ListIterator<Object>)listIterator();

  for(Objectelement :elements){

  iterator.next();

  iterator.set((E)element);

  }

  }

  在大多數情況下,您也可以使用根據 API 級別委託給其他默認實現的實現重寫List.sort ( )

  例如:

  @Override

  publicvoidsort(Comparator<?superE>comparator){

  if(Build.VERSION.SDK_INT <=25){

  Collections.sort(this);

  }else{

  super.sort(comparator);

  }

  }

  如果您選擇後者只是因為您希望開發一種適用於所有 API 級別的sort ( )函數,可以考慮賦予其一個唯一的名稱,例如sortCompat ( ),而不是重寫sort ( ) 。

  此項變更使平臺行為更加一致:現在,兩種方法都會引發ConcurrentModificationException 。

  媒體

框架會執行音頻閃避。進行 AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK時,應用不會失去焦點。新的 API 適用於需要暫停而不是閃避的應用。請注意,此行為無法在 Android O Developer Preview 1 版本中實現。

當用戶打電話時,活動的媒體流將在通話期間靜音。

所有與音頻相關的 API 都應使用 AudioAttributes而不是音頻流類型來說明音頻播放用例。僅為音量控制繼續使用音頻流類型。流類型(例如,已棄用的 AudioTrack constructor)的其他用途仍然有效,但是系統會將其記錄為錯誤。

使用 AudioTrack時,如果應用請求了足夠大的音頻緩衝區,則框架將嘗試使用深度緩衝區輸出(如果可用)。

在 Android O 中,媒體按鈕事件的處理有所不同:

在界面操作組件中處理媒體按鈕未發生變化:前臺操作組件在處理媒體按鈕時仍然優先。

如果前臺操作組件不處理媒體按鈕,系統會將媒體按鈕路由到最近在本地播放音頻的應用。在確定哪些應用接收媒體按鈕事件時,不再考慮活動狀態、標誌和媒體會話的播放狀態。即使在應用調用 setActive( false )後,媒體會話仍然可以接收媒體按鈕事件。

如果應用的媒體會話已經釋放,系統會將媒體按鈕事件發送到應用的 MediaButtonReceiver(如果有)。

對於任何其他情況,系統都會捨棄媒體按鈕事件。與其開始播放錯誤的應用,不如不播放任何東西。

  下圖匯總了新的媒體按鈕路由邏輯:

  類加載行為

  Android O 檢查確保類加載器在加載新類時不會違反運行時假設條件。不論類引用自 Java(來自 forName ( ))、Dalvik 字節碼還是 JNI,都會執行這些檢查。平臺不會攔截 Java 對 loadClass ( )函數的直接調用,也不會檢查此類調用的結果。此行為不應影響運行良好的類加載器的正常運行。

  平臺將檢查類加載器返回的類描述符是否與預期的描述符一致。如果返回的描述符與預期不符,平臺會引發 NoClassDefFoundError錯誤,並在異常日誌中存儲一條註明不一致之處的詳細錯誤消息。

  平臺還檢查請求的類描述符是否有效。此檢查捕獲間接加載諸如 GetFieldID ( )等類的 JNI 調用,向這些類傳遞無效的描述符。例如,找不到包含 java/lang/String籤名的欄位,是因為此籤名無效;它應為Ljava/lang/String; 。

  這與 JNI 對 FindClass ( )的調用不同,其中 java/lang/String是一個有效的完全限定名稱。

  Android O 不支持多個類加載器同時嘗試使用相同的 DexFile 對象來定義類。嘗試進行此操作,會導致 Android 運行時引發 InternalError錯誤,同時顯示消息 「Attempt to register dex file <filename>with multiple class loaders」 。

  DexFile API 現已棄用,強烈建議您改為使用此平臺的類加載器之一,包括 PathClassLoader或 BaseDexClassLoader。

  註:您可以創建多個引用文件系統中同一個 APK 或 JAR 文件容器的類加載器。這樣做通常不會佔用大量內存:如果存儲而不壓縮容器中的 DEX 文件,平臺可以對此類文件執行 mmap 操作,而不直接提取它們。但是,如果平臺必須從容器中提取 DEX 文件,以這種方式引用 DEX 文件可能佔用大量內存。

  在 Android 中,所有類加載器都被視為支持並行運行。當多個線程爭用同一個類加載器加載相同的類時,第一個完成此操作的線程勝出,而操作結果將用於其他線程。無論類加載器是返回同一個類、返回不同的類還是引發異常,都將發生此行為。該平臺靜默忽略此類異常。

  注意:在低於 Android O 的平臺版本中,違反這些假設條件可能導致多次定義同一個類、由於類混淆造成堆損壞和其他不良影響。

  贏取收藏版 Android 公仔

聊天的時候最怕什麼?

最怕沒有話題。

  然而,對於廣大開發者們而言,卻是從來不缺話題的。近期 Android O 成為了開發者們最為關注的熱點話題之一。因此我們希望能夠進一步增強大家對此話題的討論,探索收集開發者們對 Android 最為關心的問題。

  現在,機會來啦!不論您是想了解 Android O 還是其他的與 Android 兼容性相關 的內容,都可以在文章下方留言與我們取得聯繫。同時,我們將會在下個月的 Android 開發者 FAQ 中對小夥伴們反饋的問題進行解答。

  咳咳,還有一點要敲黑板提醒大家,為了鼓勵提問,我們將送出 3 個來此谷歌官方認證的 Android 公仔( Android Mini Collections )來獎勵提出最有價值問題的開發者,如果您已經對這款萌萌噠的 Android 公仔心動啦,那就趕快提問吧!

  我們會把有價值的問題放到 「精選留言」中,獲贊排名 前 3的開發者將收到我們的禮品!活動截止日期 2017 年 8 月 31 日,我們將在隨後的微信文章中公布獲獎的開發者!

  「知之者不如好之者,好之者不如樂之者。」還有什麼事比提問更有趣更有收穫的呢?快點行動吧!

相關焦點

  • Google I/O 2019 Android 應用原始碼現已發布
    在這篇文章中,我們將著重圍繞其中幾項主要變更進行說明。Google I/O 2019https://play.google.com/store/apps/details?手勢導航: 返回上一級界面和主屏https://developer.android.google.cn/preview/features/gesturalnavhttps://medium.com/androiddevelopers/gesture-navigation-going-edge-to-edge-812f62e4e83ehttps://github.com
  • Android Studio基礎-選項菜單Java實現實例
    void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } //Ctrl+o
  • Android - android xml 層級專題及常見問題 - CSDN
    TextView 對象上使用資源 ID 來設置文本,具體如下:TextView msgTextView = (TextView) findViewById(R.id.msg);msgTextView.setText(R.string.hello);實例考慮如下定義的布局 res/layout/activity_main.xmlandroid
  • android 布局 覆蓋 - CSDN
    項目中listview中嵌套checkbox,將父控制項設置為android:descendantFocusability="blocksDescendants",這樣設置為的是:會覆蓋子類控制項而直接獲得焦點,即點擊listview的item區域即可選中checkbox。
  • 谷歌Android Studio 和 Gradle 插件使用全新版本編號
    此項變更將 Gradle 插件從 Android Studio 的版本編號方案中剝離,並使 Android Studio 的每個版本對應於哪個年份和 IntelliJ 版本變得更加清晰。這種命名模式的變更使您能夠快速確定您在 Android Studio 中使用的 IntelliJ 平臺版本。此外,每個主要版本都將具有標準代號,從 Arctic Fox 開始,之後會按字母順序依次命名,以幫助用戶輕鬆辨別新老版本。我們建議您使用最新版本的 Android Studio,以體驗最新功能和質量改進。
  • 谷歌:Android Studio 和 Gradle 插件使用全新版本編號
    此項變更將 Gradle 插件從 Android Studio 的版本編號方案中剝離,並使 Android Studio 的每個版本對應於哪個年份和 IntelliJ 版本變得更加清晰。這種命名模式的變更使您能夠快速確定您在 Android Studio 中使用的 IntelliJ 平臺版本。此外,每個主要版本都將具有標準代號,從 Arctic Fox 開始,之後會按字母順序依次命名,以幫助用戶輕鬆辨別新老版本。我們建議您使用最新版本的 Android Studio,以體驗最新功能和質量改進。
  • 谷歌Android Studio Arctic Fox (2020.3.1) 預覽版發布,附更新內容
    此項變更將 Gradle 插件從 Android Studio 的版本編號方案中剝離,並使 Android Studio 的每個版本對應於哪個年份和 IntelliJ 版本變得更加清晰。版本說明 https://developer.android.google.cn/studio/releases對於那些嘗試使用 Jetpack Compose 的用戶,我們提供了大量更新內容,例如將 @Preview Composable 部署到設備 / 模擬器 :Jetpack Composehttps:/
  • com.android.systemui已停止是什麼意思 怎麼解決
    com.android.systemui已停止是什麼意思 怎麼解決 來源:www.18183.com作者:皮卡時間:2016-01-20 我們如果需要解決手機使用中出現com.android.systemui已停止運行的問題,那麼我們首先要搞清楚com.android.systemui
  • android啟動頁設計專題及常見問題 - CSDN
    ><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent
  • Android Spinner下拉框的基本使用
    ;java </item><item>php</item><item>xml</item><item>html</item></string-array>4、在布局文件xml的Spinner下添加:android
  • 駭極乾貨|第2期:Android日誌系統分析
    在Android系統的框架層中提供了android.util.log, android.util.Slog, android.util.Eventlog三個Java接口來向Logger日誌驅動程序中寫入日誌。
  • Android ConstraintLayout約束布局可視化工具使用~
    :constraint-layout:1.0.2'<android.support.constraint.ConstraintLayoutandroid:layout_width="match_parent"
  • 在Android 中,使用簡單的幾行代碼實現複雜、漂亮的動畫
    答案是 lottie-android。lottie-android 是 Airbnb 公司開源的框架,最低支持 Android API 16,從 lottie-android 2.8.0開始,遷移到了 androidx 項目,目前最新的版本是 lottie-android 3.4.1。
  • android app被殺原因專題及常見問題 - CSDN
    分析長按HOME鍵清理App最終會執行到ActivityManagerService.cleanUpRemovedTaskLocked方法中,ActivityManagerService類在文件"frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java"中,
  • FWUL專為Android調試和改裝而設計的Linux發行版
    這是完整的變更日誌:FWUL有自己的 主頁您可能會注意到,我將所有代碼都移到了 自己的gitlab伺服器上。github上的存儲庫。com將保留,但已歸檔,只讀和已 過時。從發布之日起更新的Manjaro Arch Linux基礎(意味著 所有OS軟體包都是最新的)此發行版的主要FWUL組件的版本:內核-> 版本:4.19.13-1 (重大升級ADB和fastboot:android- tools- > 版本:9.0.0_r18-1 (重大升級)simple-adb GUI-> 版本
  • android開發 自我優勢 - CSDN
    自我評價(案例二)Java基礎牢固,線程,集合, IO流, tcp/udp基礎網絡,基礎算法 等操作熟練熟練使用Android studio ,eclipse, postman,markdonw, wireshark等工具熟練掌握Android各項基本開發技能,如普通界面繪製,資料庫,各類原生組件,各類原生服務,生命周期等等熟練掌握
  • Android的內部存儲和外部存儲
    外部存儲: 1.需要權限<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 2.分為
  • android電源管理 - OFweek電子工程網
    framework層主要有這兩個文件:  frameworks\base\core\java\android\os\PowerManager.java  frameworks\base\services\java\com\android\server\PowerManagerService.java  其中PowerManager.java
  • 猴嗨森:2016最佳30款免費Android遊戲_三星平板電腦_平板電腦新聞...
    android-free-bean-dreamsandroid-free-crossy-roadandroid-free-platform-panicandroid-free-rust-bucket /slide/567/5678576_1.html pad.zol.com.cn
  • Android系統開機動畫的一生
    bootanimation重寫了readyToRun和threadLoop,我們直接看threadLoop:bool BootAnimation::threadLoop()bool r; // We have no bootanimation file, so we use the stock android