文笔不好,有不懂的属性可以去百度,这里不作过多解释
导入
没啥好说的,需要注意的就是别忘了加上
apply plugin: 'kotlin-kapt'
kapt {
generateStubs = true
}
在dependencies里 (我这里用的2.13 有最新就用最新的吧)
//dagger2
implementation 'com.google.dagger:dagger:2.13'
kapt 'com.google.dagger:dagger-compiler:2.13'
implementation 'com.google.dagger:dagger-android:2.13'
implementation 'com.google.dagger:dagger-android-support:2.13'
kapt 'com.google.dagger:dagger-android-processor:2.13'
进入主题
Module
这里写了个ActivityBuilderModule
@Module
abstract class ActivityBuilderModule {
@Singleton
@Binds
abstract fun application(app: MyApplication): Context
@ContributesAndroidInjector(modules = arrayOf(MainModule::class))
abstract fun bindMainActivity(): MainActivity
}
/**
* Activity里的每一个Fragment,要在module里面如下声明
* 并且Fragment还有用@Inject标注其无参构造方法
*/
@Module
abstract class MainModule {
@Binds
abstract fun bindMainFragment(mainFragment: MainFragment): Fragment
@ContributesAndroidInjector
abstract fun bindMainFragment(): MainFragment
}
Component
只需创建一个实例,有子组件可以写在modules里
AndroidSupportInjectionModule 这个module是来自Dagger.Android 用来帮助生成和定位SupComponents(子组件)
@Singleton
@Component(modules = arrayOf(AndroidSupportInjectionModule::class, ActivityBuilderModule::class))
interface AppComponent {
@Component.Builder
interface Builder {
@BindsInstance
fun application(application: Application): AppComponent.Builder
fun build(): AppComponent
}
fun inject(instance: MyApplication)
}
别忘了Make Project
Component会在自己生成一个 (Dagger+你的Component),本文的是DaggerAppComponent,然后在Application创建单例的Component
Application
1.你可以直接继承 DaggerApplication
2.如本文,继承HasActivityInjector实现,否则编译不过
@Inject
lateinit var dispatchingActivityInjector: DispatchingAndroidInjector
override fun activityInjector(): AndroidInjector {
return dispatchingActivityInjector
}
继承HasActivityInjector
class MyApplication : Application() , HasActivityInjector {
@Inject
lateinit var dispatchingActivityInjector: DispatchingAndroidInjector
override fun activityInjector(): AndroidInjector {
return dispatchingActivityInjector
}
override fun onCreate() {
super.onCreate()
DaggerAppComponent.builder().application(this)
.build().inject(this)
}
}
注入Activity和Fragment
1.你可以直接继承DaggerAppCompatActivity、DaggerFragment
2.创建BaseActivity、BaseFragment 然后继承...如下文
//BaseActivity
abstract class BaseActivity : AppCompatActivity(), HasFragmentInjector, HasSupportFragmentInjector {
@Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector
@Inject
lateinit var frameworkFragmentInjector: DispatchingAndroidInjector
override fun supportFragmentInjector(): AndroidInjector {
return supportFragmentInjector
}
override fun fragmentInjector(): AndroidInjector {
return frameworkFragmentInjector
}
override fun onCreate(savedInstanceState: Bundle?) {
AndroidInjection.inject(this)
super.onCreate(savedInstanceState)
}
}
//BaseFragment
abstract class BaseFragment : Fragment(), HasSupportFragmentInjector {
@Inject
lateinit var childFragmentInjector: DispatchingAndroidInjector
override fun supportFragmentInjector(): AndroidInjector {
return childFragmentInjector
}
@SuppressWarnings("deprecation")
override fun onAttach(activity: Activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Perform injection here before M, L (API 22) and below because onAttach(Context)
// is not yet available at L.
AndroidSupportInjection.inject(this)
}
super.onAttach(activity)
}
override fun onAttach(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// Perform injection here for M (API 23) due to deprecation of onAttach(Activity).
AndroidSupportInjection.inject(this)
}
super.onAttach(context)
}
}
Activity
ps:lateinit前不要用private 否则编译报错
class MainActivity : BaseActivity() {
@Inject
lateinit var mMainFragment: MainFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager
.beginTransaction()
.add(R.id.fragment_content, mMainFragment)
.commit()
}
}
Fragment
@Inject标注其无参构造方法
class MainFragment @Inject constructor(): BaseFragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
return inflater!!.inflate(R.layout.fragment_main, container, false)
}
}
总结坑点
- DaggerAppComponent爆红不要急,Make Project就出来了(如果能顺利编译)
- lateinit 前不要用 private 否则编译报错
- @Inject标注其无参构造方法 (@Inject constructor()),然后在Module @Binds
- 实在编译不过,再看一下本文 或 看下GitHub上的项目