头图

Hilt was released in June 2020 and provides a standardized solution for dependency injection (DI) for Android. For new projects, Hilt has compile-time verification, good runtime performance and scalability (read the article Android and Hilt limited scope for more information). However, what are the advantages of Hilt for applications that already use Dagger? Should you migrate your existing applications to Hilt? The following points explain why your team needs to invest in the migration effort.

✅ Support AndroidX extension

If you have used Dagger to process ViewModel or WorkManager , you will know that injecting your own ViewModelFactory and WorkerFactory requires a lot of template code and Dagger related knowledge. The most common implementation is to use to bind . This is one of the most complex functions in Dagger, which is often difficult for developers to understand. Hilt greatly simplifies the use of AndroidX by removing the template code. Even better, you don't even need to inject Factory into Android Framework classes, as if Hilt was not used. By using @HiltViewModel , Hilt created the correct ViewModelProvider.Factory for you. Because of this, the Activity and Fragment annotated @AndroidEntryPoint

@HiltViewModel
class PlayViewModel @Inject constructor(
  val db: MusicDatabase,
) : ViewModel() { ... }

@AndroidEntryPoint
class PlayActivity : AppCompatActivity() {

  val viewModel: PlayViewModel by viewModels()
  
  override fun onCreate(savedInstanceState: Bundle) {
    super.onCreate(bundle)
    viewModel.play()
  }
}

✅ Support test API

DI (dependency injection) should make the test easier, but the irony is that need to be tested using the Dagger lot of work . In fact, you must maintain both the formal and tested Dagger diagrams, and the implementation of is more convenient.

Hilt test can use @UninstallModules function to explicitly modify the DI relationship diagram. In addition, @BindValue are also provided, which can easily bind test fields to the DI relationship graph.

@UninstallModules(AnalyticsModule::class)
@HiltAndroidTest
class ExampleTest {

  @get:Rule
  var hiltRule = HiltAndroidRule(this)
  
  @BindValue @JvmField
  val analyticsRepository = FakeAnalyticsRepository()
  
  @Test 
  fun myTest() { ... }
}

✅ Good consistency

There are many ways to achieve the same function in Dagger. Due to the lack of guide documents for Android applications in the early days (we have solved this problem last year, such as the guide article: Dagger basics ), leading to a lot of debates in the community, and ultimately caused different developers to use and configure Dagger in Android applications The way is inconsistent.

You may have objections and think that migrating to Hilt is not worth it, because the current Dagger configuration is very complete, and you have a complete grasp of how Dagger works and how all dependencies are injected. This may be correct for you personally, but have you considered other members of the team (including potential future colleagues)? Can you ensure that it will still work when you switch to a new project? Understanding the configuration and use of Dagger in an application is a arduous and time-consuming task.

By using Hilt in the application, the above workload will be significantly reduced, because all Hilt applications use the same configuration. Developers who are new to the team will not be confused about the configuration of Hilt, because it is almost the same as their previous configuration.

✅ Support custom components

In addition to the standard components that have been defined, Hilt also provides a way to create custom components and add them to the component hierarchy. For details, see the article Hilt — Adding Components to the Hierarchy .

Although custom components reduce consistency, it will bring you great benefits! Custom components can also be used with the automatic module discovery function ( @InstallIn annotation function) and test replacement function.

However, the difference between custom components and Hilt built-in components is that these components cannot be automatically injected into the classes of the Android Framework (that is, the function of @AndroidEntryPoint

✅ Support Dagger and Hilt interaction

Hilt and Dagger can coexist! If Hilt is allowed to take over SingletonComponent , you can use Hilt features in some parts of the application and benefit from it, while other special parts still retain Dagger. This also means that can gradually complete the migration to Hilt .

❌ Does not support component dependencies

Hilt's ease of use means it makes some decisions on your behalf. Hilt adopts the sub-component mode in the component relationship. You can check the related document understand the reason for this design. If you firmly believe that your application is more suitable for component dependencies, then Hilt is not the right choice for your application.

In most projects, it is worthwhile to migrate Dagger to Hilt. Hilt brings you benefits beyond the effort required to update. We provide a lot of resources to assist in the migration, please refer to:

If you have any questions, or if you need more relevant information, please leave a comment below the article.


Android开发者
404 声望2k 粉丝

Android 最新开发技术更新,包括 Kotlin、Android Studio、Jetpack 和 Android 最新系统技术特性分享。更多内容,请关注 官方 Android 开发者文档。