網站首頁 編程語言 正文
簡單認識一下Startup
nowinandroid項目作為目前google官方來演示MAD(現代Android開發技術)的示例項目,里面大量依賴運用了jetpack包下的各種庫。通過分析學習這些庫在項中的實際使用可以幫助我們比直接閱讀庫的文檔來更好的理解和學習。希望通過學習后可以幫助到我們能熟練地在我們自己的項目中正確高效的使用到jetpack里面的各種強大庫。不廢話了,下面進入我們今天的正題——Startup
App Startup ?|? Android Developers 官網的指南有興趣可以看看
我們今天不講原理,你只需知道這個庫比之前用多個content provider去實現初始化更高效,更精確,更顯性,也就是說能合并content provider提升app的啟動速度,能準確的控制初始化順序,能清晰的從代碼知道依賴關系。僅僅這些可能jym會說,我們項目不在乎那點啟動速度的提升,也沒有很多三方庫需要走初始化等,根本用不到這個庫。
是的,我之前也是這么理解的,但是通過nowinandroid項目發現,有些jetpack內的其他庫的初始化現在也交給Startup來完成了,這一點就很重要了。意味著我們可以少寫很多樣板代碼,少寫也意味著少犯錯。所以我覺的還是有必要單獨寫一篇文章來說說Startup
編寫初始化的代碼步驟很簡單主要就分3步:
- 定義實現
Initializer
接口的實現類 - 配置manifest
- 自動或手動調用初始化操作
OK了!就這簡單3步,下面我們結合項目例子來看
項目代碼
- 先看第一步
object Sync { // This method is a workaround to manually initialize the sync process instead of relying on // automatic initialization with Androidx Startup. It is called from the app module's // Application.onCreate() and should be only done once. fun initialize(context: Context) { AppInitializer.getInstance(context) .initializeComponent(SyncInitializer::class.java) } } internal const val SyncWorkName = "SyncWorkName" /** * Registers work to sync the data layer periodically on app startup. */ class SyncInitializer : Initializer<Sync> { override fun create(context: Context): Sync { WorkManager.getInstance(context).apply { // Run sync on app startup and ensure only one sync worker runs at any time enqueueUniqueWork( SyncWorkName, ExistingWorkPolicy.KEEP, SyncWorker.startUpSyncWork(), ) } return Sync } override fun dependencies(): List<Class<out Initializer<*>>> = listOf(WorkManagerInitializer::class.java) }
定一個SyncInitializer
類實現了泛型為Sync
的Initializer
接口。需要重寫接口定義的兩個方法:
- ?
create()
?方法, 它包含初始化組件所需的所有操作,并返回一個Sync
的實例. - ?
dependencies()
?方法, 返回當前初始化器需要依賴的其他初始化器集合,我們可以用這個方法來變相的實現各個初始化器的執行順序。
所以在create
方法里面的執行WorkManager.getInstance(context)
方法是安全的。我們這篇只關注Startup所以我們只用知道在這個地方WorkManager做了些事情就行,后面會另開一篇單獨講WorkManager。為啥是安全的呢?因為在dependencies
方法里面先執行了WorkManagerInitializer::class.java
初始化。我們再來看看這個類。
public final class WorkManagerInitializer implements Initializer<WorkManager> { private static final String TAG = Logger.tagWithPrefix("WrkMgrInitializer"); @NonNull @Override public WorkManager create(@NonNull Context context) { // Initialize WorkManager with the default configuration. Logger.get().debug(TAG, "Initializing WorkManager with default configuration."); //這個地方已經完成了單例的構建,后面再調用WorkManager.getInstance(context)獲取實例,否則報錯 WorkManager.initialize(context, new Configuration.Builder().build()); return WorkManager.getInstance(context); } @NonNull @Override public List<Class<? extends androidx.startup.Initializer<?>>> dependencies() { //這里WorkManager的初始化不需要其他初始化構造器,所以返回的是個空集合 return Collections.emptyList(); } }
以上我們就把第一步走完了,現在再來看第二步
- 再看第二步
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <application> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <!-- TODO: b/2173216 Disable auto sync startup till it works well with instrumented tests --> <meta-data android:name="com.google.samples.apps.nowinandroid.sync.initializers.SyncInitializer" android:value="androidx.startup" tools:node="remove" /> </provider> </application> </manifest>
這里需要注意的是tools:node="remove"
,在provider層級用的話是全局取消自動初始化,在meta-data層級用的話是單個組件取消自動初始化。例子展示的是單個組件取消自動初始化。另外注意的一點是被依賴的初始化組件是不需要再另外在manifest里面聲明的,這就是為什么WorkManagerInitializer
沒有聲明。
- 最后一步
@HiltAndroidApp class NiaApplication : Application(), ImageLoaderFactory { override fun onCreate() { super.onCreate() // Initialize Sync; the system responsible for keeping data in the app up to date. Sync.initialize(context = this) } /** * Since we're displaying SVGs in the app, Coil needs an ImageLoader which supports this * format. During Coil's initialization it will call `applicationContext.newImageLoader()` to * obtain an ImageLoader. * * @see <a >Coil</a> */ override fun newImageLoader(): ImageLoader { return ImageLoader.Builder(this) .components { add(SvgDecoder.Factory()) } .build() } }
上面的代碼是app的Application,我們今天的重點是Startup,所以我們先不管其他的。只用看onCreate
下的Sync.initialize(context = this)
方法。
object Sync { // This method is a workaround to manually initialize the sync process instead of relying on // automatic initialization with Androidx Startup. It is called from the app module's // Application.onCreate() and should be only done once. fun initialize(context: Context) { AppInitializer.getInstance(context) .initializeComponent(SyncInitializer::class.java) } }
AppInitializer.getInstance(context).initializeComponent(SyncInitializer::class.java)
傳入SyncInitializer
類,實現手動初始化完成。
原文鏈接:https://juejin.cn/post/7195036376650711097
相關推薦
- 2024-02-28 UNI-APP設置屏幕保持常亮
- 2022-05-06 Linq中ToList()和CopyToDataTable()用法詳解_實用技巧
- 2023-01-02 Kotlin?LinearLayout與RelativeLayout布局使用詳解_Android
- 2022-03-16 C#中獲取二維數組的行數和列數以及多維數組各個維度的長度_C#教程
- 2022-11-17 一文講解如何獲取k8s容器里運行的jar包_云其它
- 2022-06-30 PyTorch詳解經典網絡種含并行連結的網絡GoogLeNet實現流程_python
- 2022-04-16 pycharm如何為函數插入文檔注釋_python
- 2023-04-09 C語言中的分支循環其嵌套語句_C 語言
- 最近更新
-
- 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同步修改后的遠程分支