如何使用 Hilt Bind/Provide Activity 或 Fragment?
How to Bind/Provide Activity or Fragment with Hilt?
我正在尝试在 Android 应用程序上实现 Hilt,虽然与 Dagger 相比,它很容易实现并且删除了很多样板代码,但有些东西我想念,比如构建我的自己的组件并自己确定它们的范围,所以我将拥有自己的职位。
要点:示例:假设我有一个简单的应用程序,其中包含 RecyclerView、适配器、Acitivity 和嵌套在我的适配器中的回调,我将其传递到我的适配器构造函数中以检测点击或其他任何内容,我让我的 activity 实现回调,当然我想注入适配器。
class @Inject constructor (callBack: Callback): RecyclerView.Adapter...
当我让 Hilt 知道我想注入我的适配器时,我需要让 Hilt 知道如何提供所有适配器依赖项 - 回调。
在 Dagger 中,我只需将 Activity 绑定到我的一个模块中的回调即可实现此目的:
@Binds fun bindCallback(activity: MyActivity): Adapter.Callback
Dagger 知道如何绑定 Activity(或任何 Activity/Fragment),然后将其链接到该回调,但对于 Hilt 它不起作用。
我怎样才能做到这一点?我如何提供或绑定 Activity 或 Fragment with Hilt?
Hilt 可以提供泛型 Activity
(和 Fragment
的实例)作为 ActivityComponent
(和 FragmentComponent
中的依赖项)。它只是无法提供您特定 MyActivity
.
的实例
你仍然可以create your own Component
in Hilt。您只需要自己管理 component
实例。添加 MyActivity
作为组件构建器的种子数据,您应该能够 @Bind
您的 Callback
没有问题。
解决方法很简单。
所以前几天回来看看我的问题,发现还是没有新的解决方案,所以我尝试了Bartek的解决方案,也没能解决,即使解决了,干净的 Hilt 代码变得太乱了,所以我做了一点调查和玩了一点,发现解决方案实际上非常简单。
它是这样的:
应用程序:
@HiltAndroidApp
class MyApp: Application()
Activity: (实现回调)
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), SomeClass.Callback {
@Inject
lateinit var someClass: SomeClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onWhatEver() {
// implement
}
}
SomeClass:(带内部回调)
class SomeClass @Inject constructor(
private val callback: Callback
) {
fun activateCallback(){
callback.onWhatEver()
}
interface Callback{
fun onWhatEver()
}
}
SomeModule: (providing/binding activity 回调)
@Module
@InstallIn(ActivityComponent::class)
object SomeModule{
@Provides
fun provideCallback(activity: Activity) =
activity as SomeClass.Callback
}
这就是我们所需要的。
我们无法使用 @Bind 将 activity 绑定到回调,因为它需要显式提供并转换为回调,以便应用程序可以构建。
模块安装在 ActivityComponent 中,并且知道通用 'activity',如果我们将其转换为回调,Hilt 是内容并且 activity 绑定到回调,只要在特定的 activity 范围内,Hilt 就会知道如何提供回调。
多个Activities/Fragments
应用程序:
@HiltAndroidApp
class MyApp: Application()
书籍Activity:
@AndroidEntryPoint
class BooksActivity : AppCompatActivity(), BooksAdapter.Callback{
@Inject
lateinit var adapter: BooksAdapter
...
override fun onItemClicked(book: Book) {...}
}
}
作者Activity:
@AndroidEntryPoint
class AuthorsActivity : AppCompatActivity(), AuthorsAdapter.Callback{
@Inject
lateinit var adapter: AuthorsAdapter
...
override fun onItemClicked(author: Author) {...}
}
图书适配器
class BooksAdapter @Inject constructor (
val callback: Callback
) ... {
...
interface Callback{
fun onItemClicked(book: Book)
}
}
作者适配器
class AuthorsAdapter @Inject constructor (
val callback: Callback
) ... {
...
interface Callback{
fun onItemClicked(auhtor: Auhtor)
}
}
作者模块
@Module
@InstallIn(ActivityComponent::class)
object AuthorsModule {
@Provides
fun provideCallback(activity: Activity) =
activity as AuthorsAdapter.Callback
}
书籍模块
@Module
@InstallIn(ActivityComponent::class)
object BooksModule {
@Provides
fun provideCallback(activity: Activity) =
activity as BooksAdapter.Callback
}
模块可以毫无问题地合并到一个模块中,只需更改函数的名称即可。
这当然适用于更多活动and/or多个片段..适用于所有逻辑案例。
我正在尝试在 Android 应用程序上实现 Hilt,虽然与 Dagger 相比,它很容易实现并且删除了很多样板代码,但有些东西我想念,比如构建我的自己的组件并自己确定它们的范围,所以我将拥有自己的职位。
要点:示例:假设我有一个简单的应用程序,其中包含 RecyclerView、适配器、Acitivity 和嵌套在我的适配器中的回调,我将其传递到我的适配器构造函数中以检测点击或其他任何内容,我让我的 activity 实现回调,当然我想注入适配器。
class @Inject constructor (callBack: Callback): RecyclerView.Adapter...
当我让 Hilt 知道我想注入我的适配器时,我需要让 Hilt 知道如何提供所有适配器依赖项 - 回调。
在 Dagger 中,我只需将 Activity 绑定到我的一个模块中的回调即可实现此目的:
@Binds fun bindCallback(activity: MyActivity): Adapter.Callback
Dagger 知道如何绑定 Activity(或任何 Activity/Fragment),然后将其链接到该回调,但对于 Hilt 它不起作用。
我怎样才能做到这一点?我如何提供或绑定 Activity 或 Fragment with Hilt?
Hilt 可以提供泛型 Activity
(和 Fragment
的实例)作为 ActivityComponent
(和 FragmentComponent
中的依赖项)。它只是无法提供您特定 MyActivity
.
你仍然可以create your own Component
in Hilt。您只需要自己管理 component
实例。添加 MyActivity
作为组件构建器的种子数据,您应该能够 @Bind
您的 Callback
没有问题。
解决方法很简单。
所以前几天回来看看我的问题,发现还是没有新的解决方案,所以我尝试了Bartek的解决方案,也没能解决,即使解决了,干净的 Hilt 代码变得太乱了,所以我做了一点调查和玩了一点,发现解决方案实际上非常简单。
它是这样的:
应用程序:
@HiltAndroidApp
class MyApp: Application()
Activity: (实现回调)
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), SomeClass.Callback {
@Inject
lateinit var someClass: SomeClass
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onWhatEver() {
// implement
}
}
SomeClass:(带内部回调)
class SomeClass @Inject constructor(
private val callback: Callback
) {
fun activateCallback(){
callback.onWhatEver()
}
interface Callback{
fun onWhatEver()
}
}
SomeModule: (providing/binding activity 回调)
@Module
@InstallIn(ActivityComponent::class)
object SomeModule{
@Provides
fun provideCallback(activity: Activity) =
activity as SomeClass.Callback
}
这就是我们所需要的。 我们无法使用 @Bind 将 activity 绑定到回调,因为它需要显式提供并转换为回调,以便应用程序可以构建。
模块安装在 ActivityComponent 中,并且知道通用 'activity',如果我们将其转换为回调,Hilt 是内容并且 activity 绑定到回调,只要在特定的 activity 范围内,Hilt 就会知道如何提供回调。
多个Activities/Fragments
应用程序:
@HiltAndroidApp
class MyApp: Application()
书籍Activity:
@AndroidEntryPoint
class BooksActivity : AppCompatActivity(), BooksAdapter.Callback{
@Inject
lateinit var adapter: BooksAdapter
...
override fun onItemClicked(book: Book) {...}
}
}
作者Activity:
@AndroidEntryPoint
class AuthorsActivity : AppCompatActivity(), AuthorsAdapter.Callback{
@Inject
lateinit var adapter: AuthorsAdapter
...
override fun onItemClicked(author: Author) {...}
}
图书适配器
class BooksAdapter @Inject constructor (
val callback: Callback
) ... {
...
interface Callback{
fun onItemClicked(book: Book)
}
}
作者适配器
class AuthorsAdapter @Inject constructor (
val callback: Callback
) ... {
...
interface Callback{
fun onItemClicked(auhtor: Auhtor)
}
}
作者模块
@Module
@InstallIn(ActivityComponent::class)
object AuthorsModule {
@Provides
fun provideCallback(activity: Activity) =
activity as AuthorsAdapter.Callback
}
书籍模块
@Module
@InstallIn(ActivityComponent::class)
object BooksModule {
@Provides
fun provideCallback(activity: Activity) =
activity as BooksAdapter.Callback
}
模块可以毫无问题地合并到一个模块中,只需更改函数的名称即可。
这当然适用于更多活动and/or多个片段..适用于所有逻辑案例。