Kotlin+Dagger2+MVP框架搭建(一)

Kotlin+Dagger2+MVP框架搭建(一)

一、项目配置

app:build.gradle文件中

apply plugin: 'kotlin-kapt'
android {
、、、
}
dependencies {
、、、
    //dagger2依赖添加
    implementation 'com.google.dagger:dagger:2.21'
  //(注意Dagger官网使用的是annotationProcessor,可能出现各种问题,建议使用Kapt)
     kapt 'com.google.dagger:dagger-compiler:2.21'
}
二、简单使用Dagger

1.新建接口声明MainActivity的View接口(MVP中的V)和Presenter接口(MVP中的P)

interface MainControl {

    interface View {
        fun setData(user: User)
    }

    interface Presenter {
        fun setData()
    }
}

2.新建一个数据类模拟Model中提供的数据

data class User(val name: String,val id: Int)

3.新建Model
注:可以理解为是一个内容提供者类,需要@Module标签修饰类,提供内容的方法前需要@Provides标签修饰

@Module
class MainModel(private val view: MainControl.View) {

    @Provides
    fun providerView(): MainControl.View {
        return view
    }

    @Provides
    fun providerUser(): User {
        return User("张三", 100)
    }
}

4.新建Component
注:这是一个必要的接口,可以理解为容器,用于包容Model产生的东西,需要使用@Component(…)标签修饰接口,用于指定包含的Model。其中modules的值是指向直接包含的Model文件集合,dependencies的值指向所依赖的附属Component文件集合,dependencies后面叙说,这里暂时只用modules

@Component(modules = arrayOf(MainModel::class))
interface MainComponent {
    fun inject(activity: MainActivity)
}

5.新建Presenter
需要实现 MainControl.Presenter 接口,并使用@Inject标签修饰构造函数,表明需要注入的参数

class MainPresenter @Inject
constructor(private val view: MainControl.View,private val user: User) : MainControl.Presenter {
    override fun setData() {
        view.setData(user)
    }
}

6.在Activity中实现MainControl.View接口,并“Build->Make Project”(或者Ctrl+F9)构建一下项目,使之自动生成Dagger所需文件。然后添加如下代码:

class MainActivity : AppCompatActivity(), MainControl.View {

    //用于注入Presenter对象
    @Inject
    lateinit var presenter: MainPresenter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //Build之后添加,用于初始化,并生成Model中两个方法提供的对象
        DaggerMainComponent.builder().mainModel(MainModel(this))
                .build()
                .inject(this)
        presenter.setData()
    }

    override fun setData(user: User) {
       Toast.makeText(this,user.name,Toast.LENGTH_SHORT).show()
    }
}
三、依赖组件Component

1.新建Model,并注释掉MainModel类中providerUser()方法
注:因为Model中不能直接提供两个返回类型相同的对象,所以这里为了方便观察Component的依赖将MainModel中的providerUser()方法注释掉

@Module
class UserModel() {
    @Provides
    fun providerUser(): User {
        return User("李四", 200)
    }
}

@Module
class MainModel(private val view: MainControl.View) {

    @Provides
    fun providerView(): MainControl.View {
        return view
    }
}

2.新建Component

@Component(modules = arrayOf(UserModel::class))
interface UserComponent {
   fun getData() : User
}

3.修改MainComponent

@Component(modules = arrayOf(MainModel::class),dependencies = arrayOf(UserComponent::class))
interface MainComponent {
    fun inject(activity: MainActivity)
}

4.“Build->Make Project”(或者Ctrl+F9)构建一下项目,并将MainActivity做如下修改:

class MainActivity : AppCompatActivity(), MainControl.View {

    @Inject
    lateinit var presenter: MainPresenter
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //修改,用于依赖UserComponent
        DaggerMainComponent.builder().mainModel(MainModel(this))
                .userComponent(DaggerUserComponent.builder().userModel(UserModel()).build())
                .build()
                .inject(this)
                
        presenter.setData()
    }

    override fun setData(user: User) {
       Toast.makeText(this,user.name,Toast.LENGTH_SHORT).show()
    }
}
四、 @Qualifier 和 @Named标签使用

这两个标签用于区分Model中存在被 @Provides标签修饰的返回对象类型相同的方法
注:以下代码基于第二步时的代码修改
注:因Kotlin中变量编译为 Java 字节码的时候会对应三个目标,一个是变量本身、还有 getter 和 setter,所以需要使用field标记指定@Qualifier 和 @Named标签应用到 变量上(解释来源Kotlin中国)

1、@Named标签使用

注:在@Named(“…”)中的字符串是标记常量,Dagger就是通过标记常量查找对应方法的,所以使用时前后标记需要一致

1.修改MainControl

interface MainControl {

    interface View {
        fun setData(user: User)
    }

    interface Presenter {
   	    //修改
        fun setData(user: User)
    }
}

2.修改MainPresenter

class MainPresenter @Inject
constructor(private val view: MainControl.View) : MainControl.Presenter {
    override fun setData(user: User) {
        view.setData(user)
    }
}

3.修改MainModel

@Module
class MainModel(private val view: MainControl.View) {

    @Provides
    fun providerView(): MainControl.View {
        return view
    }

    @Provides
    @Named("tag1")
    fun providerUser(): User {
        return User("张三", 100)
    }

    @Provides
    @Named("tag2")
    fun providerUser2(): User {
        return User("李四", 200)
    }
}

修改MainActivity

class MainActivity : AppCompatActivity(), MainControl.View {

    @Inject
    lateinit var presenter: MainPresenter
    
    @Inject
    @field:Named("tag1")
    lateinit var user1: User

    @Inject
    @field:Named("tag2")
    lateinit var user2: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        DaggerMainComponent.builder().mainModel(MainModel(this))
                .build()
                .inject(this)
        presenter.setData(user1)
        presenter.setData(user2)
    }

    override fun setData(user: User) {
       Log.e("User","  name:"+user.name+"  id:"+user.id)
    }
}

2、@Qualifier 标签使用

1.新建@Qualifier标签Tag1和Tag2两个文件

@Qualifier
annotation class Tag1


@Qualifier
annotation class Tag2

2.使用Tag1和Tag2替换@Named使用位置

@Module
class MainModel(private val view: MainControl.View) {

    @Provides
    fun providerView(): MainControl.View {
        return view
    }

    @Provides
    @Tag1
    fun providerUser(): User {
        return User("张三", 100)
    }

    @Provides
    @Tag2
    fun providerUser2(): User {
        return User("李四", 200)
    }
}


class MainActivity : AppCompatActivity(), MainControl.View {

    @Inject
    lateinit var presenter: MainPresenter
    
    @Inject
    @field:Tag1
    lateinit var user1: User

    @Inject
    @field:Tag2
    lateinit var user2: User

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        DaggerMainComponent.builder().mainModel(MainModel(this))
                .build()
                .inject(this)
        presenter.setData(user1)
        presenter.setData(user2)
    }

    override fun setData(user: User) {
       Log.e("User","  name:"+user.name+"  id:"+user.id)
    }
}
链接

Kotlin中国:https://kotlintc.com/articles/2679
Dagger2入门:https://www.jianshu.com/p/92f793e76654

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值