成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在 Android 和 Hilt 中限定作用域

移動開發(fā) Android
將對象 A 的作用域限定到對象 B,指的是對象 B 的整個生命周期內(nèi)始終持有相同的 A 實(shí)例。當(dāng)涉及到 DI (依賴項(xiàng)注入) 時,限定對象 A 的作用域?yàn)橐粋€容器,則意味著該容器在銷毀之前始終提供相同的 A 實(shí)例。

將對象 A 的作用域限定到對象 B,指的是對象 B 的整個生命周期內(nèi)始終持有相同的 A 實(shí)例。當(dāng)涉及到 DI (依賴項(xiàng)注入) 時,限定對象 A 的作用域?yàn)橐粋€容器,則意味著該容器在銷毀之前始終提供相同的 A 實(shí)例。

[[339194]]

在 Hilt 中,您可以通過注解將類型的作用域限定在某些容器或組件內(nèi)。例如,您的應(yīng)用中有一個處理登錄和注銷的 UserManager 類型。您可以使用@Singleton 注解將該類型的作用域限定為ApplicationComponent (ApplicationComponent 是一個被整個應(yīng)用的生命周期管理的容器)。被限定作用域的類型在應(yīng)用組件中沿組件層次結(jié)構(gòu)向下傳遞: 在本案例中,相同的 UserManager 實(shí)例將被提供給層次結(jié)構(gòu)內(nèi)其余的 Hilt 組件。應(yīng)用中任何依賴于 UserManager 的類型都將獲得相同的實(shí)例。

  • 組件層次結(jié)構(gòu)https://developer.android.google.cn/training/dependency-injection/hilt-android#component-hierarchy

注意: 默認(rèn)情況下,Hilt 中的綁定都未限定作用域。這些綁定不屬于任何組件,并且可以在整個項(xiàng)目中被訪問。每次被請求都會提供該類型的不同實(shí)例。當(dāng)您將綁定的作用域限定為某個組件時,它會限制您使用該綁定的范圍以及該類型可以具有的依賴項(xiàng)。

在 Android 中,您不使用 DI 庫也可以通過 Android Framework 來手動限定作用域。讓我們看看如何手動限定作用域,以及如何改用 Hilt 來限定作用域。最后,我們將比較使用 Android Framework 手動限定作用域和使用 Hilt 限定作用域的區(qū)別。

在 Android 中限定作用域

看了上文的定義,您可能會有這樣的異議: 在某個特定類中使用一個類型的實(shí)例變量也可以做到限定該變量類型的作用域。沒錯!不使用 DI 時,您可以執(zhí)行如下操作:

  1. class ExampleActivity : AppCompatActivity() { 
  2.   private val analyticsAdapter = AnalyticsAdapter() 
  3.   ... 

analyticsAdapter 變量的作用域被限定為 MyActivity 的生命周期,這意味著只要 Activity 沒有被銷毀,該變量就是同一個實(shí)例。如果另一個類出于某種原因需要訪問這個被限定了作用域的變量,每次訪問也會獲得相同實(shí)例。當(dāng)新的MyActivity 實(shí)例被創(chuàng)建時 (如系統(tǒng)設(shè)置改變),一個新的 AnalyticsAdapter 實(shí)例將會被創(chuàng)建。

使用 Hilt,等效代碼如下:

  1. @ActivityScoped 
  2. class AnalyticsAdapter @Inject constructor() { ... } 
  3.  
  4. @AndroidEntryPoint 
  5. class ExampleActivity : AppCompatActivity() { 
  6.  
  7.  @Inject lateinit var analyticsAdapter: AnalyticsAdapter 
  8.  

每次創(chuàng)建的 MyActivity 都會持有一個 ActivityComponent DI 容器的新實(shí)例,在 Activity 被銷毀之前,該實(shí)例將向組件層次結(jié)構(gòu)下的依賴項(xiàng)提供相同的AnalyticsAdapter 實(shí)例。

  • 組件層次結(jié)構(gòu)https://developer.android.google.cn/training/dependency-injection/hilt-android#component-hierarchy


更改系統(tǒng)設(shè)置后,您將獲得一個新的 AnalyticsAdapter 和 MainActivity 實(shí)例

通過 ViewModel 限定作用域

然而,我們可能希望 AnalyticsAdapter 可以在系統(tǒng)設(shè)置更改后留存!或者說,我們希望直到用戶離開 Activity 之前,都限定該實(shí)例的作用域?yàn)?Activity。

為此,您可以使用組件架構(gòu)中的 ViewModel,因?yàn)樗梢栽谙到y(tǒng)設(shè)置更改后留存。

  • 組件架構(gòu)中的 ViewModelhttps://developer.android.google.cn/topic/libraries/architecture/viewmodel

不使用依賴項(xiàng)注入時,您可能有如下代碼:

  1. class AnalyticsAdapter() { ... } 
  2.  
  3. class ExampleViewModel() : ViewModel() { 
  4.   val analyticsAdapter = AnalyticsAdapter() 
  5.  
  6. class ExampleActivity : AppCompatActivity() { 
  7.  
  8.   private val viewModel: ExampleViewModel by viewModels() 
  9.   private val analyticsAdapter = viewModel.analyticsAdapter 
  10.  

通過這種方式,您將 AnalyticsAdapter 的作用域限定為 ViewModel。因?yàn)?Activity 具有 ViewModel 的訪問權(quán)限,所以在該 Activity 中可以始終獲得相同的 AnalyticsAdapter 實(shí)例。

通過使用 Hilt,您可以通過限定 AnalyticsAdapter 的作用域?yàn)锳ctivityRetainedComponent 來實(shí)現(xiàn)相同的行為,因?yàn)锳ctivityRetainedComponent 也可以在系統(tǒng)設(shè)置更改后留存。

  1. @ActivityRetainedScoped 
  2. class AnalyticsAdapter @Inject constructor() { ... } 
  3.  
  4. @AndroidEntryPoint 
  5. class ExampleActivity : AppCompatActivity() { 
  6.  
  7. @Inject lateinit var analyticsAdapter: AnalyticsAdapter 
  8.  

 

通過使用 ViewModel 或者 Hilt 中的 ActivityRetainedScope 注解,您可以在系統(tǒng)設(shè)置更改后獲得相同的實(shí)例

 

如果您希望在遵循良好的 DI 實(shí)踐的同時,保留 ViewModel 用于處理視圖邏輯,您可以使用 @ViewModelInject 提供 ViewModel 的依賴項(xiàng),該注解的詳細(xì)描述請參見: 文檔 | 使用 Hilt 注入 ViewModel 對象。這樣一來,AnalyticsAdapter 的作用域就無需被限定為ActivityRetainedComponent,因?yàn)榇藭r它的作用域被手動限定為 ViewModel:

  • 文檔 | 使用 Hilt 注入 ViewModel 對象https://developer.android.google.cn/training/dependency-injection/hilt-jetpack#viewmodels
  1. class AnalyticsAdapter @Inject constructor() { ... } 
  2.  
  3. class ExampleViewModel @ViewModelInject constructor( 
  4.   private val analyticsAdapter: AnalyticsAdapter 
  5. ) : ViewModel() { ... } 
  6.  
  7. @AndroidEntryPoint 
  8. class ExampleActivity : AppCompatActivity() { 
  9.  
  10.   private val viewModel: ExampleViewModel by viewModels() 
  11.   private val analyticsAdapter = viewModel.analyticsAdapter 
  12.  

我們剛才所看到的內(nèi)容,可以應(yīng)用到任何由 Android Framework 生命周期類管理的 Hilt 組件中。點(diǎn)擊查看全部可用作用域。回到我們最初的示例,將作用域限定為 ApplicationComponent,等同于不使用 DI 框架時在 Application 類中持有該實(shí)例。

  • 全部可用作用域https://developer.android.google.cn/training/dependency-injection/hilt-android#component-scopes

對比 Hilt 及 ViewModel 限定作用域

使用 Hilt 限定作用域,優(yōu)勢為您可在 Hilt 組件層次結(jié)構(gòu)中使用被限定的類型;而對于 ViewModel,則必須通過 ViewModel 手動訪問被限定作用域的類型。

使用 ViewModel 限定作用域,優(yōu)勢為您可以在應(yīng)用中任何 LifecyclerOwner對象中持有 ViewModel。例如,如果您使用了 Jetpack Navigation 庫,則可以將 ViewModel 綁定到 NavGraph 上。

  • LifecyclerOwner https://developer.android.google.cn/reference/androidx/lifecycle/LifecycleOwner
  • Jetpack Navigation 庫https://developer.android.google.cn/guide/navigation/navigation-getting-started
  • NavGraphhttps://developer.android.google.cn/reference/androidx/navigation/fragment/NavHostFragment

Hilt 提供的作用域數(shù)量有限。可能沒有符合您特定使用場景的作用域。例如嵌套 Fragment,對于這種情況,您可以退一步使用 ViewModel 限定作用域。

使用 Hilt 注入 ViewModel

如上文所述,您可以使用 @ViewModelInject 向 ViewModel 注入依賴項(xiàng)。其原理是這些綁定關(guān)系保存在 ActivityRetainedComponent 中,這也是為什么您只能注入未限定作用域的類型,或者是限定作用域?yàn)锳ctivityRetainedComponent 以及 ApplicationComponent 的類型。

如果 Activity 或 Fragment 被 @AndroidEntryPoint 注解修飾,就可以通過getDefaultViewModelProviderFactory() 方法獲取 Hilt 生成的 ViewModel 工廠了。由于可以在 ViewModelProvider 中使用這些 ViewModel 工廠,使您獲取 ViewModel 的方式變得更加靈活。例如: 將作用域限定為BackStackEntry 的 ViewModel。

限定作用域會有一些代價,因?yàn)樘峁┑膶ο笤诔钟姓弑讳N毀之前將一直保留在內(nèi)存中。請?jiān)趹?yīng)用中慎重地考慮使用限定作用域的對象。如果對象的內(nèi)部狀態(tài)要求使用同一實(shí)例,對象需要同步,或者對象的創(chuàng)建成本很高,那么限定作用域是恰當(dāng)?shù)淖龇ā?/p>

當(dāng)然,當(dāng)您需要限定作用域時,您可以使用 Hilt 中的作用域注解,也可以直接使用 Android Framework。

責(zé)任編輯:未麗燕 來源: 谷歌開發(fā)者
相關(guān)推薦

2011-09-06 09:56:24

JavaScript

2019-03-13 08:00:00

JavaScript作用域前端

2021-03-09 08:35:51

JSS作用域前端

2017-09-14 13:55:57

JavaScript

2011-03-18 09:27:00

Spring

2010-01-22 11:13:44

三層交換機(jī)

2021-06-02 07:02:42

js作用域函數(shù)

2021-07-06 11:40:28

Android框架代碼

2019-03-10 08:13:28

物聯(lián)網(wǎng)戰(zhàn)場海洋

2022-08-24 16:50:59

人工智能機(jī)器學(xué)習(xí)DevOps

2023-09-05 08:23:56

SpringScope方法

2020-03-24 08:32:24

vue作用域前端

2011-05-12 18:26:08

Javascript作用域

2010-09-25 16:10:09

添加DHCP作用域

2021-07-01 07:34:08

NLP推薦系統(tǒng)

2021-12-06 07:15:48

Javascript作用域閉包

2010-06-13 17:21:41

Linux下dhcp測

2009-06-01 11:16:48

PHP網(wǎng)站開發(fā)變量作用域

2010-05-25 16:04:45

VoIPVoWLAN

2021-03-17 08:39:24

作用域作用域鏈JavaScript
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 精品国产精品三级精品av网址 | 一级黄色片在线免费观看 | 欧美精品在线一区二区三区 | 国产视频二区 | 午夜精品一区二区三区三上悠亚 | 成人在线小视频 | 亚洲第一色站 | 亚洲日本乱码在线观看 | 国产中文在线观看 | 亚洲综合首页 | 男人天堂手机在线视频 | 国产精品18hdxxxⅹ在线 | 欧美久久免费观看 | 免费av电影网站 | 日本亚洲欧美 | 亚洲精品视频在线 | 国产精品视频在线观看 | 日本精品一区二区三区在线观看视频 | 亚洲一区二区在线视频 | 精品久久久网站 | 国产精品国产a | 欧美一级免费片 | 中文字幕成人av | 狠狠骚 | 国产精品看片 | 国产剧情一区 | 欧美自拍第一页 | 美女爽到呻吟久久久久 | 亚洲一区二区三区四区五区中文 | 国产精品精品视频一区二区三区 | 久久91| 久久国产精品视频 | 久一精品| 久久国产区 | 国产高清一区二区三区 | 亚洲伦理自拍 | 自拍偷拍亚洲一区 | 久久久久国产一区二区三区四区 | 七七婷婷婷婷精品国产 | 伊人艹 | 国产精品亚洲综合 |