[英]Inject abstract class (base activity) with HILT
我剛剛開始嘗試在我非常簡單的項目中使用 Hilt。 現在一切都在 Dagger2 上,但我想遷移到 Hilt。
我有一個活動:
@AndroidEntryPoint
class MainActivity : BaseActivity() {
// SOME STUFF
}
像這樣的 BaseActivity:
abstract class BaseActivity : AppCompatActivity() {
// SOME STUFF
}
另外,我有一個 class 使用 baseActivity 來顯示一個對話框。 例如:
@FragmentScoped
class TestComponentImpl @Inject constructor(
private val baseActivity: BaseActivity
) : TestComponent {
override fun displayDialog() {
MaterialDialog(baseActivity).show { ...
}
}
但是,當我嘗試編譯時,出現此錯誤:
如果沒有 @Provides-annotated 方法,就無法提供 BaseActivity。
所以,我的問題是:如何構造函數注入一個抽象的 class。 我嘗試了很多東西但沒有成功,就像在 Hilt 模塊中這樣:
@Provides
@Singleton
fun provideBaseActivity(): BaseActivity{
return BaseActivity() // Of course, it can't work cause it's an abstract class
}
或者(就像我對 Dagger 所做的那樣):
@Provides
@PerActivity
fun appCompatActivity(baseActivity: BaseActivity) = baseActivity as AppCompatActivity
另外,我只是 Hilt 的初學者,所以,也許我錯過了一些東西。 我會繼續尋找:)
感謝您的時間和回答:)
編輯:
這幾天我自己搜索了一下,這似乎有效,但似乎不太好......
@Singleton
@Provides
fun provideBaseActivity(baseActivity: BaseActivity): AppCompatActivity {
return baseActivity
}
但只有當我這樣放置我的 baseActivity 時:
open class BaseActivity Inject constructor() : AppCompatActivity()
但是,在那之后,如果我嘗試像這樣在我的 TestComponentImpl 中使用注入的 baseActivity(就像我在 Hilt 之前使用 Dagger 所做的那樣):
override fun displayError() {
Snackbar.make(
baseActivity.findViewById(android.R.id.content),
"My error text",
Snackbar.LENGTH_LONG
).apply {
show()
}
我還有另一個錯誤:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()' on a null object reference
所以我不認為我的 baseActivity 注入做得很好。 我正在繼續調查;)
有點hacky(類型轉換)但應該可以工作(未經測試,寫下我的頭頂,所以如果有什么不按預期工作,請隨時告訴我):
創建這樣Module
:
@Module
@InstallIn(ActivityComponent::class)
object BaseActivityModule {
@Provides
fun provideBaseActivity(activity: Activity): BaseActivity {
check(activity is BaseActivity) { "Every Activity is expected to extend BaseActivity" }
return activity as BaseActivity
}
}
最后一次as BaseActivity
可能是不必要的。 Kotlin 編譯器應該處理這個問題。
@Boysteuf @Bartek Lipinski
面對以下錯誤:
error: [Dagger/MissingBinding] android.app.Activity cannot be provided without an @Inject constructor or an @Provides-annotated method.
public abstract static class SingletonC implements EzeApp_GeneratedInjector,
^
android.app.Activity is injected at
com.ezetap.consumerpaymentsdk.di.module.BaseActivityModule.provideBaseActivity(activity)
com.ezetap.consumerpaymentsdk.base.BaseSDKActivity is injected at
com.ezetap.consumerpaymentsdk.di.module.AppModule.provideServicePresenterPresenter(baseSDKActivity, …)
com.ezetap.consumerpaymentsdk.presenters.ServicePresenter is injected at
com.ezetap.consumerpaymentsdk.activity.ServiceSDKActivity.presenter
com.ezetap.consumerpaymentsdk.activity.ServiceSDKActivity is injected at
com.ezetap.consumerpaymentsdk.activity.ServiceSDKActivity_GeneratedInjector.injectServiceSDKActivity(com.ezetap.consumerpaymentsdk.activity.ServiceSDKActivity) [com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.SingletonC → com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.ActivityRetainedC → com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.ActivityC]
The following other entry points also depend on it:
com.ezetap.consumerpaymentsdk.activity.SimActivity_GeneratedInjector.injectSimActivity(com.ezetap.consumerpaymentsdk.activity.SimActivity) [com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.SingletonC → com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.ActivityRetainedC → com.ezetap.consumerpaymentsdk.base.EzeApp_HiltComponents.ActivityC]
@Module(includes = [NetworkModule::class , BaseActivityModule::class ])
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideBasePresenter(baseSDKActivity: BaseSDKActivity ,ezeApi: EzeApi, @ApplicationContext context: Context ) : BaseSDKPresenter {
return BaseSDKPresenter(baseSDKActivity, ezeApi , context )
}
@Provides
@Singleton
fun provideSimPresenter(baseSDKActivity: BaseSDKActivity, ezeApi: EzeApi , @ApplicationContext context: Context ) : SimPresenter {
return SimPresenter(baseSDKActivity , ezeApi , context)
}
@Provides
@Singleton
fun provideServicePresenterPresenter(baseSDKActivity: BaseSDKActivity,ezeApi: EzeApi , @ApplicationContext context: Context ) : ServicePresenter {
return ServicePresenter(baseSDKActivity , ezeApi , context)
}
}
@Module
@InstallIn(ActivityComponent::class)
object BaseActivityModule {
@Provides
fun provideBaseActivity(activity :Activity): BaseSDKActivity {
check(activity is BaseSDKActivity) { "Every Activity is expected to extend BaseActivity" }
return activity as BaseSDKActivity
}
}
open class BaseSDKActivity @Inject constructor() : AppCompatActivity() {
}
@ActivityScoped
open class BaseSDKPresenter @Inject constructor(private val baseSDKActivity: BaseSDKActivity , private val ezeApi: EzeApi ,
private val context: Context )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.