Android targetSdkVersion 升級到 26 總結

因爲各個應用市場要求,須要在 2019年5月1日 以前把 target 升級到 26。因此對本公司全網的 App 和可能影響到的相關 SDK 作一個升級。本文主要記錄這次升級的過程和解決的一些問題。html

其實升級 target 技術含量不是很高,可是由於涉及到庫(100 多個 SDK)和人員,依賴有點多,涉及到公司全部業務的 App, 並且改動的地方和細節也有多,很容易出現考慮不全,致使線上問題。android

主要過程爲如下幾步:git

  • 查看官方文檔
  • 找下「輪子」,選擇一個合適本身的「輪子」, 優化「輪子」
  • 修改對應的模塊和 App,並接入到相關的業務方
  • 遇到的問題,解決問題

查看官方文檔

由於公司的 App、組件、模塊都是基於 target 22 和 support 24 進行開發的,因此要看下官方文檔 releases/platformslibraries/support-library 相關的文檔,從中找到影響點。咱們受影響主要有 2 個方面:github

  • 1、運行時權限申請,(這個是大頭)
  • 2、其餘問題

找輪子

由於第一個權限問題是比較廣泛的,因此應該有相關的開源項目支持,爲了效率,咱們就不重複製造輪子。參考各個比較流行的開源方案,作了一下對比:工具

相關庫 須要修改 Activity 或者 Fragment 設置界面跳轉 備註 star 數
AndPermission 不須要 有, 能夠參考 改動小 4911
Permissions4m 須要 有,能夠參考 改動多 1594
RxPermissions 須要,不支持 Application 請求傳入請求 無,須要本身實現 改動多 7911
FcPermissions 須要,須要繼承 FcPermissionsCallbacks 無,須要本身實現 改動多 406
EasyPermission 須要 改動多 7526
PermissionHelper 須要繼承 BasePermissionActivity 改動多 1191

經過以上對比,咱們決定使用 AndPermission 的方案,由於這個對於咱們現有 App 的侵入是最少的,改動點比較少,並且支持 Appliction 傳入(其實當使用 Application 傳入時候,會有問題,後面再說)。測試

說下 AndPermission

當時的考慮點是咱們公司不少 SDK 設計的時候是沒有 Activity 的引用。可是咱們的 SDK, 基本有個 Application 這個引用的,因此選擇了一個可以支持傳入 Applicaiton 就可以判斷權限回調的庫。爲何 AndPermission 可以支持呢?由於 AndPermission 在權限校驗的時候會啓動 PermissionActivity,而且加上了 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);,全部的權限請求都是在這個 PermissionActivity 處理,並且改動也比較少。優化

AndPermission 這個庫的動態權限請求具體過程大夥能夠看下 AndPermission 這個庫的源碼。使用方式以下:ui

從 API 調用來看是十分簡單好用的。而後我又仔細看了一下它的實現過程,發現了有些不符合咱們產品需求的地方:.net

  1. 業務方接入須要簡單,須要有一套默認的權限申請失敗提示框
  2. 彈框提醒權限必須是 Activity 的。可是 AndPermission 是支持 Application 傳入的,那麼就會有問題
  3. 好比我用戶點擊某個按鈕致使後面的方法鏈中有可能連續調用屢次的權限請求,那麼就可能一次會彈出不少個框

這樣咱們就須要在 AndPermission 基礎上進行改造,作出適合本身的動態權限庫。咱們自定義了默認的 onDenied (申請權限失敗後的回調)。 這樣業務方就不須要關心失敗後怎麼提示了,只要關心成功後把以前的業務邏輯放到成功後這裏執行就行了。權限申請失敗提示框,用來啓動一個 Activity 來 show 這個 Dialog,這樣即便在前面傳入的是 Application 的 context 也是沒有問題了。對於屢次請求權限致使屢次彈框的問題,咱們在 AndPermission 的基礎上添加的請求隊列,只有上一個權限請求處理完成後,才進行下一次權限請求,這樣的話,即便用戶一次行爲的方法鏈過程當中有不少次請求也不會屢次彈框。 而後當我用隊列管理請求權限的時候,很怕某個權限阻塞了,或者出了未知異常,因此我對每次權限加入過程作了超時處理。以上幾點是對於本身業務場景的幾點考慮,進行的改造。插件

修改各個 SDK 和 App

U51AndPermission SDK 已經生成了,那接下來就是怎麼集成到各個 SDK 和 App 中了。首先咱們要知道,咱們的 App 哪些地方有可能調用到了須要權限請求的 API。若是要人工去看效率實在是過低了。咱們有 100 多個庫,不可能把庫看完且不出錯。因此咱們使用了以前同事的一個插件去掃描相關的 API,用來定位到可能出現權限的類在哪裏,用的是哪一個庫。這樣就提升了準確率和效率。

這個是咱們插件須要搜索的 API

如下是部分搜索結果

按照這種方法,咱們本須要處理 100 多個類庫的,如今只有 20 個不到。一會兒少了 4 倍的工做量,並且相對準確。

App 「必選權限」方案選擇和問題處理

不少 App 啓動的時候須要一些必選權限的,咱們的 App 也是同樣的,須要在 App 啓動的時候驗證一個必選權限。若是有必選權限,那麼提示用戶受權,若是不受權,那麼就不可以繼續使用咱們的產品了。因此進入 App 主要功能前,須要一個前置的攔截。考慮過 2 種方案:

  • 方案1、在 Applicaiton 的 onCreate 方法中去申請必選權限,讓啓動 Activity 等待 Application 中權限申請好了,再用消息(EventBus) 通知 啓動 Activity 繼續走下去的流程

  • 方案2、新建一個新的 啓動 Activity,在這個 Activity 中作申請權限,申請完後再去啓動以前老的啓動 Activity

和對接的業務方討論,他們選擇了第一種方案, 這麼作的緣由也是由於咱們不少 SDK 的初始化代碼在 Appliction 中,咱們必需要在初始化 SDK 以前就應該把必要權限拿到。若是選擇第二種,那麼咱們的初始化代碼須要移動到新的啓動 Activity 中,這樣改動風險有點高。

接入代碼以下:

對接完後有幾個咱們遇到的問題須要提下:

問題1、 由於在 App 啓動的時候,若是沒有必要權限,那麼就會有彈框讓用戶設置權限,這時候用戶點擊 "設置",就會跳轉到 App 設置權限頁面,當用戶受權回來的時候,有部分手機會出現黑屏。致使黑屏的緣由是 U51Permission 傳入進去的 context 是 Application。若是是 Activity 就不會黑屏。因此解決方法是使用 Activity 去請求權限,回調方式是使用 Application.registerActivityLifecycleCallbacks,以下:

問題2、 由於咱們有些邏輯是放到先後臺切換的代碼裏面的,先後切換的主要用主要用到 Application.registerActivityLifecycleCallbacks 這個回調,根據 Activity 的生命週期統計來切換先後臺(先後臺的切換邏輯是使用統計 activity 的個數來實現的);因此 Application.registerActivityLifecycleCallbacks 這個操做應該是在 啓動 Activity 以前就應該被註冊。可是在申請必要權限的時候,我先啓動 Activity 後再去註冊這個 callback 的,因此致使啓動 Activity 不在計算範圍內,致使先後臺的調用邏輯不許確,業務邏輯處理時機不對的問題。後來咱們使用一個本身的 registerActivityLifecycleCallbacks,命名 MyActivityLifecycleCallbacks,在 Application 一開始啓動的時候就註冊了,而後把後面其餘須要註冊的地方放到 MyActivityLifecycleCallbacks 中,由它統一通知其餘須要先後臺的回調。

替換以前

替換以後

能夠看出來替換後改動代碼不多,並且全部的先後臺切換都會統一到本身的 MyActivityLifecycleCallbacks 裏面進行集中管理。

其餘問題

還有其餘相關問題,網上都可以找到,我就列舉一下,你們本身注意一下就行了:

  1. Android 7.0 相機相關問題
  2. 須要顯示的註冊廣播
  3. 黑白名單限制, debug 包會有彈框提示,release包是沒有的;可是這個須要注意,之後可能會有問題;也能夠用掃描工具掃描一下這份名單
  4. 懸浮框實現的 LayoutParams.TYPE變更
  5. android.os.FileUriExposedException 的異常,文件共享的限制和第 1 條同樣
  6. Sevices.startService 有些手機會奔潰,這個咱們的 App 以前就處理過了
  7. vivo 手機相機權限問題
  8. NotificationManager 應該使用 builder 去建立,須要有個 channel, Android 8.0 的修改
  9. 榮耀 8 手機,scrollView 嵌套 recycleView 顯示不全的問題
  10. Toast 相關的問題

總結

以上就是本次升級須要的修改點了,剩下的還有測試、灰度和正式上線。從整個適配過程來看,這個需求其實不是很難,可是從改動的點來講,溝通協調能力要求仍是很高的,會涉及到大部分客戶端開發、測試和產品。

對於改造升級大範圍的基礎庫,每一個環節儘可能多思考和團隊成員多討論,切記不要一我的悶頭就是幹。但也不要過多的擔憂,須要膽大心細,這樣才能把事情推動下去。好了,target 28 的適配也立刻要來了。


做者介紹

  • Mr.Jie,51信用卡客戶端基礎組 Android 開發工程師,目前主要負責客戶端創新項目相關技術演進工做。
相關文章
相關標籤/搜索