網站首頁 編程語言 正文
StartUp是為了App的啟動提供的一套簡單、高效的初始化方案。
ContentProvider中初始化
在項目中會需要用到很多的第三方庫,而很多第三方庫都提供了顯示的調用初始化接口,需要在Application中進行初始化,并獲取到Application的Context。
于是乎,Application中的代碼就可能會變成這個樣子:
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
A.initialize(this)
B.initialize(this)
C.initialize(this)
...
}
...
}
隨著引入的第三方庫越來越多,Application中的代碼也是越來越龐大。
于是乎,有些更加聰明的庫設計者,他們想到了一種非常巧妙的辦法來避免顯示的調用初始化接口,而是可以自動調用初始化接口,這種辦法就是借助ContentProvider。
ContentProvider作為Android四大組件之一,其主要作用是跨應用程序共享數據。
然而這些第三方庫并沒有打算使用ContentProvider來跨應用程序共享數據,只是準備使用它拿到Context進行初始化而已。在APP的啟動流程中,有一步就是要執行到程序中所有注冊過的ContentProvider的onCreate方法,所以這些第三方庫的初始化就默默自動完成了。
這種設計方式可以將庫的用法進一步簡化,不需要主動去調用初始化接口,而是將這個工作在背后悄悄自動完成了,給集成庫的開發者們帶來了很大的便利。很多庫都用到了這種方法,比如Facebook,Firebase。
但是呢,看上去如此巧妙的技術方案,有一個很大的缺點就是,ContentProvider會增加許多額外的耗時。因為不同的庫就定義了不同的ContentProvider類,多了這么多ContentProvider,ContentProvider作為四大組件之一,啟動也是耗時的,自然也就增加App啟動消耗的時間了。
這時候就需要App Startup來對此情況進行優化了。
App Startup
首先來看一下官網對于Startup的簡介:
The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.
Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.
主要說到了兩點特性:
- 明確設置初始化順序
- 共享單個ContentProvider
其實,App Startup內部也是創建了一個ContentProvider,并提供了一套用于初始化的標準。然后對于其他第三方庫來說,就不需要再自己創建ContentProvider了,都按Startup這套標準進行實現就行了。同時Startup還提供了可以設置初始化順序。
App Startup使用
首先,引入庫:
implementation 'androidx.startup:startup-runtime:1.1.1'
然后定義一個用于執行初始化的Initializer,并實現App Startup庫的Initializer接口:
class ARouterInitializer : Initializer<String> {
override fun create(context: Context): String {
ARouter.init(context.applicationContext as Application)
return "ARouterInit"
}
override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}
實現Initializer接口要求重寫兩個方法,在create()方法中可以進行初始化操作,這里以ARouter發初始化為例。
dependencies()方法表示,當前的初始化是否還依賴于其他的Initializer,如果有的話,就在這里進行配置,App Startup會保證先初始化依賴的Initializer,然后才會初始化當前,這樣就可以設置初始化順序了。當然,絕大多數的情況下,初始化操作都是不會依賴于其他Initializer的,所以通常直接返回一個emptyList()就可以了。
最后,在AndroidManifest.xml中進行配置,這里需要嚴格按照Startup的配置規范:
<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.example.base.ARouterInitializer" android:value="androidx.startup" /> </provider>
只有meta-data中的android:name部分需要指定成自定義的Initializer的全路徑類名,其他部分都是不能修改的,否則App Startup庫可能會無法正常工作。
tools:node="merge"標簽就是用來合并所有申明了InitializationProvider的ContentProvider。
延遲初始化
如果不希望初始化在應用啟動的時候自動初始化,App Startup也是提供了手動調用初始化的方法。
<!-- 禁用所有InitializationProvider組件初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" tools:node="remove" /> <!-- 禁用單個InitializationProvider組件初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.example.base.ARouterInitializer" tools:node="remove" /> </provider>
使用tools:node="remove"標簽,這個標簽用于告訴manifest merger tool,在最后打包成APK時,將所有該名稱的節點全部刪除。可以禁用所有InitializationProvider組件初始化,也可以禁用單個InitializationProvider組件初始化。
AppInitializer.getInstance(this).initializeComponent(ARouterInitializer::class.java)
然后再手動調用App Startup提供的初始化方法。
原文鏈接:https://blog.csdn.net/yuantian_shenhai/article/details/126688831
相關推薦
- 2022-02-21 docker啟動容器錯誤:docker: Error response from daemon: O
- 2022-06-27 Python深拷貝與淺拷貝引用_python
- 2022-10-27 教你快速搭建?React?Native?開發環境_React
- 2022-11-24 Flask中Cookie和Session理解與作用介紹_python
- 2022-06-26 Docker上部署Nginx的方法步驟_docker
- 2022-06-29 python打印經典故事從前有座山的幾種寫法_python
- 2022-06-01 C語言?詳解如何刪除有序數組中的重復項_C 語言
- 2022-02-28 獲取元素的寬度,高度
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支