Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 詳解Android N適配要點

詳解Android N適配要點

編輯:關於Android編程

Google即將發布的Android7.0的預覽版Android_N為我們增加了許多新的特性,其中包括多窗口的支持、通知欄支持直接回復、網絡數據節省開關、以及新的DOZE模式等;下面我們就來談一談關於這些新功能的適配問題和需要注意的地方。

 

1.Doze(打盹模式)更加強大

該模式是在Android6.0中引入的,當用戶設備未插電源、處於靜止狀態屏幕關閉時,該模式會推遲CPU和網絡活動,從而增加電池壽命。

在Android_N中對這種模式進行了加強,當設備處於充電狀態且屏幕已關閉一定時間後,設備會進入打盹模式並應用第一部分限制:關閉應用網絡訪問、推遲作業和同步。如果進入打盹模式後設備處於靜止狀態達到一定時間,系統則會對 PowerManager.WakeLock、AlarmManager 鬧鈴、GPS 和 Wi-Fi 掃描應用余下的打盹限制。無論是應用部分還是全部打盹限制,系統都會喚醒設備以提供簡短的維護時間窗口,在此窗口期間,應用程序可以訪問網絡並執行任何被推遲的作業/同步。

這種情況倒也好辦,要麼就是讓用戶將自己的的應用加入白名單,

或則在代碼中使用Intent的方式跳轉到設置頁面,讓用戶去設置;

Google推薦我們使用Schedule的方式來管理我們的任務,我們可以設置讓這些任務在特定的時候才去執行,比如將任務設置運行在充電或則無限制的時候運行,如下就是加入一個網絡無限制的任務:

 

\

 

Google在API 23中為我們加入了一個新的Action,我們可以通過調用這個Action跳轉到指定頁面指導用戶設置白名單:

 

\

 

\

在Doze模式中還有一種Standby的模式,這個模式相對更嚴格,如果對於及時通信的軟件在未加入白名單的情況下,處於該模式不能收到及時的提示,必須從該模式恢復才能收到,因此需要特別注意,我們可以從google的官方文檔當中查到進入該模式的ADB指令:

\

將第二條指令中的true改為false即可恢復,這個便於開發和測試。

2.禁止一些廣播的行為

在之前的Android系統中,我們開啟一個監聽事件的廣播後,程序在事件觸發的時候就會觸發我們的廣播,而且不值一個程序會收到通知,所以在Android_N中對CONNECTIVITY_ACTION、ACTION_NEW_PICTURE和ACTION_NEW_VIDEO三個廣播進行了處理。

a)面向 Android N 開發的應用不會收到 CONNECTIVITY_ACTION 廣播,但是對於一個前台程序則不會受到限制例如:CONNECTIVITY_CHANGE。

b)應用無法發送或接收 ACTION_NEW_PICTURE 或 ACTION_NEW_VIDEO 廣播。此項優化會影響所有應用,而不僅僅是面向 Android N 的應用。

未來的 Android 版本還可能會棄用其他隱式廣播以及未綁定的後台服務。有鑒於此,您應避免依賴在清單文件中聲明的接收器來偵聽隱式廣播或刪除此依賴關系,以及避免或刪除對後台服務的依賴關系。

 

3.權限機制的限制

AndroidN做了一些權限更改,包括用戶帳戶權限和向外部存儲設備寫入信息的新權限,這些更改可能會影響您的應用。下面概要列出了預覽版中已發生更改的權限。   GET_ACCOUNTS(已棄用)   GET_ACCOUNTS權限現已棄用。對於面向AndroidN的應用,系統將忽略此權限。   下面我們就來著重的談一談關於這個權限修改,從Android6.0開始Google引入了權限動態申請的機制,在之前的版本中,我們申請權限都是一次性在應用的Manifest文件中將我們程序所需要的權限,在用戶安裝App的時候一起向用戶申請,這樣會造成要麼用戶沒有仔細看就直接同意安裝了,為後期帶來安全隱患,要麼用戶不同意應用程序無法安裝,但是對於一個app來說,可能有的權限不是我們必須的,因此Google在Android6.0中就引入了動態申請權限的機制。   該機制面向於6.0以上的版本,並且在6.0中將targetVersion指定為23,否者效果和之前的版本一樣。   我們就拿這個向外部存儲卡進行寫操作的權限來舉例。   當我們需要向外部存儲卡進行寫操作的時候,我們需要遵循如下的步驟:   a).查詢是否具有該權限:  

 

\

這裡面需要注意的是,為了向下兼容,ContextCompat和ActivityCompat的導入的是support.v4包下的

\

hasPerMission就是查詢的返回值,如果返回true就表示我們已經具有了權限,可以直接進行操作,如果是false的話,我們就需要向用戶動態的申請寫的權限了,如下:

\

這個函數類似於我們常用的startActivityForResult的方法,它會觸發一個回調,其中REQUEST_WRITE_CODE就是我們自定義的請求碼。

b).處理請求的回調

\

\

 

當請求權限時就會在用戶的屏幕上彈出如上的界面,用戶點擊拒絕或者同意都會觸發我們上面的回調函數,如果同意就返回true,否者就會返回false。

這種情況下,當用戶點擊同意後,下次再次訪問就不需要再次申請了,如果用戶點擊拒絕,當用戶下次再次請求的時候該彈出框還會再次出現,這裡我需要額外補充的是,在我們開發模式的時候,如果我們之前選擇了同意某項權限後,當我們沒有卸載程序而是直接又一次編譯程序,此時系統認為我們具有了權限;另一點值得注意的就是這些權限用戶是可以動態取消的,所以一個健壯的程序應當做好判斷。

上面的方法是在6.0引入的,這種方式雖然可以達到我們往外部寫存儲卡的目的,但是也帶來了這種權限申請機制與當初的動態申請權限的初衷有一定的出入,所以在Android_N中我們改用另一種更好的方式,這種方式將我們的權限范圍設定的更加的准確。

使用 StorageManager 類獲取適當的 StorageVolume實例。然後,通過調用該實例的 StorageVolume.createAccessIntent() 方法創建一個 Intent。使用此 Intent 訪問外部存儲目錄。 若要獲取所有可用卷的列表,包括可移動介質卷,請使用 StorageManager.getVolumesList()。

該種方式將請求權限用向特定的目錄發一個Intent的形式,然後觸發我們的onActivityResult()的方法,

注意:有一點需要特別注意的就是,StorageVolume 這個類是在Android_N

的sdk版本中引入的,所以如果你的編譯版本不是Android_N的話,就不要用這個方法了,否者編譯都通過不了。

下面我們就將請求外部存儲卡上的DIRECTORY_PICTURES目錄作為例子:

\

如果用戶授予訪問權限,則系統會調用onActivityResult()的重寫方法,且結果代碼為Activity.Result_OK,Intent包含URL。使用提供的URL訪問目錄信息,與使用存儲訪問框架返回的URL類似。

如果用戶不同意,則結果碼為Activity.Result_CANCELED,Intent的數據為空。

\

以上是對回調的處理,getActivity().getContentResolver().takePersistableUriPermission是存儲我們請求的URl地址,將其保存下來,下次我們再次請求就不會再彈出讓用戶確認的界面了,返回結果就直接是RESULT_OK。

\

上面這張表是對是否需要請求權限的小統計數據。

4.JNI中不再允許調用非公有的API

JNI中不允許調用非公有API,由於命名空間的變化,在Android_N上運行會奔潰,需要切換到對應的公有API,此類問題在大多數的APP中都存在,值得特別注意.為幫助診斷問題,Google為我們給出了錯誤代碼的示例:

Java錯誤示例:

\

NDK錯誤示例:

\

Google提供的一些典型的修復辦法:

a).可以使用標准 JNI 函數來替代使用 libandroid_runtime.so 中的 getJavaVM 和 getJNIEnv:

\

b).可以使用公開備選項 __system_property_get 來替代使用 libcutils.so 中的 property_get 符號。如需這樣做,請使用 __system_property_get 及以下 include 函數:

\

c).應使用應用本地版本來替代使用 libcrypto.so 中的 SSL_ctrl 符號。例如,您應在 .so 文件中靜態鏈接 libcyrpto.a,或者在應用中包含您自己的來自 BoringSSL 或 OpenSSL 的動態 libcrypto.so。

5.屏幕支持縮放功能:

Android_N支持用戶設置顯示尺寸,可以放大或縮小屏幕上的所有元素,但是用戶無法將屏幕寬度縮放至低於sw320dp。

當設備密度發生更改時,系統會以如下方式通知正在運行的應用:

如果是面向 API 級別 23 或更低版本系統的應用,則系統會自動終止其所有後台進程。這意味著如果用戶切換離開此類應用,轉而打開 Settings 屏幕並更改 Display size 設置,則系統會像處理內存不足的情況一樣終止該應用。如果應用具有任何前台進程,則系統會如處理運行時變更中所述將配置變更通知給這些進程,就像對待設備屏幕方向變更一樣。

如果是面向 Android N 的應用,則其所有進程(前台和後台)都會收到有關配置變更的通知,如處理運行時變更中所述。

大多數應用並不需要進行任何更改即可支持此功能,不過前提是這些應用遵循 Android 最佳實踐。具體要檢查的事項:

在屏幕寬度為 sw320dp 的設備上測試您的應用,並確保其充分運行。

當設備配置發生變更時,更新任何與密度相關的緩存信息,例如緩存位圖或從網絡加載的資源。當應用從暫停狀態恢復運行時,檢查配置變更。

注:如果您要緩存與配置相關的數據,則最好也包括相關元數據,例如該數據對應的屏幕尺寸或像素密度。保存這些元數據便於您在配置變更後決定是否需要刷新緩存數據。

避免用像素單位指定尺寸,因為像素不會隨屏幕密度縮放。應改為使用與密度無關像素 (dp) 單位指定尺寸。

多屏模式:

Google在Android_N中支持了多屏模式,我們可以在Manifest文件中配置Activity的android:resizeableActivity=["true"|"false"]來讓其是否支持,默認是支持的。

特別注意的一點是:一個根Activity的設置屬性將會被應用到所有在這個Task棧中的Activity。

帶來的問題

a).應用如要支持多窗口,也有一些需要注意的地方,最主要的是分辨率的適配。在多窗口模式下,應用的顯示比例不一定是手機屏幕的比例。而且在屏幕未做滑動處理的時候會導致頁面內容的缺失,這裡可能會影響到一些代碼,比如應用一啟動就全局存儲一下屏幕的寬高,在N下可能就有問題了,需要開發者做相應的修改。

b).在多屏模式以下特性無法使用:應用無法隱藏狀態欄如果他不是全屏模式下。

c).系統忽略android:screenOrientation屬性(無法根據屏幕方向來旋轉App的界面)。

6.Android N 逐漸將JDK8.0引入

A)ArrayList實現中的私有屬性array被移除,反射使用該屬性的需要注意下

B)隨機數種子調用可能出錯,Crypt安全提供商在OpenJdk中不提供,而它在大家調用SecureRandom.serSeed()設置隨機種子時會用到,OpenJDK中需要通過SecretKeySpec去直接加載原始密鑰或者使用真正的密鑰導出函數。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved