現代 Android 應用程式通常使用 Kotlin、AndroidX、Jetpack 函式庫與 Jetpack Compose。平台 API 仍位於 android.*;AndroidX 在 androidx.* 中提供具版本相容性且較高階的 API。應用程式套件具有多個由系統管理的進入點,而不是傳統的全程序 main() 方法。
應用程式隔離 #
Android 會為已安裝套件指派 Linux UID,並為其私有檔案提供以 UID 為基礎的擁有權。應用程式程序會執行自己的 Android Runtime 實例,而跨套件元件呼叫使用 Binder IPC。執行時期權限、SELinux 與框架服務檢查會補充 UID 邊界。
共用 UID 過去可供簽章相同的套件使用,但已不建議新應用程式採用,因為它會削弱套件隔離。應用程式應透過明確介面共用資料,例如受權限保護的內容提供者、文件選擇器、URI 授予或 Binder 服務,而不是透過私有路徑。
元件與資訊清單 #
Android 有四種元件類型:
- activity 容納聚焦的使用者介面。
- service 在沒有 activity UI 的情況下執行工作。長時間的使用者可見工作需要前景服務通知,且受平台限制。
- broadcast receiver 對廣播執行短暫回應,應將長時間工作委派給適當的排程器。
- content provider 透過
ContentResolverAPI 暴露結構化資料。
資訊清單會宣告應用程式元件、權限、必要時的套件可見性、最低 SDK 層級、功能與應用程式中繼資料。只有在 android:exported 設定與適用權限允許時,具有 intent filter 的元件才可從外部定址。保持非公開元件未匯出。
Intent 與元件啟用 #
明確 intent 會識別特定元件。隱含 intent 描述動作、資料、類別與選用 extras;系統會依照已匯出的 intent filter 解析它。對內部操作與服務使用明確 intent,因為隱含服務 intent 可能解析到非預期元件。
Activity 透過 startActivity 或 Activity Result API 啟動。服務依其執行模型使用 startService、startForegroundService 或 bindService。內容提供者透過 ContentResolver 接收操作。不需要立即執行的背景工作應放在 WorkManager,或在適當時使用 JobScheduler,而不是長時間背景服務。
將所有傳入的 intent、extras 與 URI 視為不受信任輸入。在 API 允許時驗證呼叫端,驗證值,為敏感元件要求權限,並只在必要的最小範圍與最短時間內授予 URI 權限。
Activity 生命週期與狀態 #
系統以 onCreate 建立 activity,透過 onStart 使其可見,再透過 onResume 使其可互動。onPause 表示 activity 已失去前景焦點;它必須快速返回。當 activity 不再可見時會接著呼叫 onStop,這是釋放僅在可見期間需要的資源之適當位置。
activity 物件可能因要求執行 finish,或因系統回收其程序而被銷毀。後者可使用 onSaveInstanceState 儲存小型且可重建的 UI 狀態。框架會儲存支援的檢視階層狀態,但應用程式狀態應依大小與生命週期放在 ViewModel、saved-state handle、資料庫或其他持久儲存中。不要使用生命週期 callback 執行無界網路交易或資料庫遷移。
資源 #
Android 資源系統會將 res/ 項目編譯為 R.string.app_name 等產生的識別碼。將每個資源放在具型別的頂層目錄,例如 layout、drawable、mipmap、values、xml、font、menu、raw 或 animator。放在 assets/ 的資產不會編譯到 R,而是透過 AssetManager 開啟。
資源限定詞會依設定、地區設定、螢幕大小、密度、方向與夜間模式選取最適當的替代項。限定詞必須使用文件化順序,且不能重複限定詞型別。應用程式參照的每項資源都要保留預設資源,因為裝置設定可能不符合專用替代項。
Kotlin、Jetpack 與 Compose #
Kotlin 提供 null 安全、擴充函式、lambda、sealed type 與協程。AndroidX 與 Jetpack 提供具生命週期感知能力的元件、Navigation、Room、WorkManager 與相容性 API。lifecycleScope 與 viewModelScope 將協程繫結到擁有者,但取消並不免除讓工作具冪等性與處理失敗的需求。
Jetpack Compose 將 UI 表達為可組合函式。activity 以 setContent 進入 Compose;收集到組合中的可觀察狀態會使受影響的 UI 重新組合。LazyColumn 提供有效率的項目式配置,而修飾詞表達配置、互動與裝飾。
將畫面狀態保留在 ViewModel 中,讓可組合函式主要成為狀態的函式,並對生命週期取決於組合的工作使用 effect API。View 與 Compose 可以在分階段遷移期間互通,因此採用 Compose 不需要重寫全部內容。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)