Jam*_*ley 5 android dependency-injection kotlin dagger-2
我对 Daggers 依赖注入还很陌生。我正在使用 Dagger 2 和 Kotlin 开发一个新应用程序。我从一个用于构建的基本入门应用程序开始。在 App.kt 中,每个活动都会自动注入,到目前为止这非常酷。然而,我现在在实施 Facebook 和 Google 社交登录时遇到了问题。
当应用程序尝试启动 Facebook 或 Google 登录活动时,我收到错误消息:
"No injector factory bound for Class<external.activities.classNameHere>"
我无法 @Provides 这些外部类,因为它们没有实现 @Module 注释。
我的临时解决方案是在自动注入之前检查正在注入的活动,并跳过那些外部类。虽然这看起来有点奇怪,我想知道是否有更好的解决方案或者我是否遗漏了一些东西。我可以看到这个 if 语句随着时间的推移变得相当长。
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks() {
override fun onActivityCreated(p0: Activity?, p1: Bundle?) {
p0?.let {
if (p0 is FacebookActivity || p0 is CustomTabMainActivity || p0 is CustomTabActivity ) {
Log.d("KSULog", "App.kt is not injecting activity " + p0.toString())
}
else {
AndroidInjection.inject(p0)
}
}
}
})
}
Run Code Online (Sandbox Code Playgroud)
谢谢参观。
做到这一点的方法非常简单。如果你看看Google Samples,你就会有一个明确的方向。喜欢GitHubBrowserSample
所以你将创建一个interface Injectable像这样的,基本上是一个标记界面。
/**
* Marks an activity / fragment injectable.
*/
interface Injectable
Run Code Online (Sandbox Code Playgroud)
每个活动或片段都会实现这个接口,例如这样(在 Kotlin 中)
open class BaseActivity : AppCompatActivity(),Injectable {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory
lateinit var baseActivityViewModel: BaseActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AndroidInjection.inject(this)
baseActivityViewModel = ViewModelProviders.of(this, viewModelFactory)
.get(BaseActivityViewModel::class.java)
}
Run Code Online (Sandbox Code Playgroud)
}
重要的几行是:
open class BaseActivity : AppCompatActivity(),Injectable
AndroidInjection.inject(this)
Run Code Online (Sandbox Code Playgroud)
创建一个 Activity 模块来贡献 Activity 对象
/**
* Module to contribute all the activities.
*/
@Module
abstract class ActivityModule {
@ContributesAndroidInjector
internal abstract fun contributeSplashActivity(): SplashActivity
}
Run Code Online (Sandbox Code Playgroud)
最后DaggerInjector启用注入
/**
* Helper to inject all the activities and fragments that are marked Injectable.
*/
object DaggerInjector {
fun injectAll(application: TurtleApp) {
DaggerAppComponent.builder()
.application(application)
.build().inject(application)
application
.registerActivityLifecycleCallbacks(object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
injectComponents(activity)
}
override fun onActivityStarted(activity: Activity) {
}
override fun onActivityResumed(activity: Activity) {
}
override fun onActivityPaused(activity: Activity) {
}
override fun onActivityStopped(activity: Activity) {
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
}
override fun onActivityDestroyed(activity: Activity) {
}
})
}
private fun injectComponents(activity: Activity) {
if (activity is Injectable) {
AndroidInjection.inject(activity)
}
// (activity as? FragmentActivity)?.supportFragmentManager?.registerFragmentLifecycleCallbacks(
// object : FragmentManager.FragmentLifecycleCallbacks() {
// override fun onFragmentCreated(fm: FragmentManager?, f: Fragment?,
// savedInstanceState: Bundle?) {
// if (f is Injectable) {
// AndroidSupportInjection.inject(f)
// }
// }
// }, true)
}
}
Run Code Online (Sandbox Code Playgroud)
取消注释代码以启用Fragment注入。
| 归档时间: |
|
| 查看次数: |
1916 次 |
| 最近记录: |