Android 活动之间的 Dagger 2 单例

Dagger 2 Singleton between Android Activities

我想了解@Singleton 如何在 Dagger 2 上工作

build.gradle

implementation 'com.google.dagger:dagger:2.32'
kapt 'com.google.dagger:dagger-compiler:2.32'

Vehicle.kt

@Singleton
class Vehicle @Inject constructor() {

    var speed = 0
}

AppComponent.kt

@Singleton
@Component
interface AppComponent {

    fun inject(activity: MainActivity)

    fun inject(activity: SecondActivity)
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var mVehicle: Vehicle

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        DaggerAppComponent.create().inject(this)

        mVehicle.speed = 75
    }
}

SecondActivity.kt

class SecondActivity : AppCompatActivity() {

    @Inject
    lateinit var mVehicle: Vehicle

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_second)

        DaggerAppComponent.create().inject(this)

        Log.d(TAG, "Vehicle speed: ${mVehicle.speed}")
    }
}

我希望在 SecondActivity 上看到 Vehicle speed 75,但它是 0。我确定一定有我遗漏或误解的东西,只是想不通。

问题是基于您正在创建 DaggerAppComponent 的多个实例这一事实。你必须创建一次组件,将它存储在某处(objectApplication),然后使用它进行注入。组件的每个实例都代表一个完整的、独立的依赖关系图。

像这样的东西应该会按预期工作:

@Singleton
@Component
interface AppComponent {
    fun inject(activity: FirstActivity)
    fun inject(activity: SecondActivity)
}

object ComponentHolder {
    val component: AppComponent by lazy { DaggerAppComponent.create() }
}

class FirstActivity : AppCompatActivity() {

    @Inject lateinit var mVehicle: Vehicle

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ComponentHolder.component.inject(this)

        mVehicle.speed = 75
    }
}

class SecondActivity : AppCompatActivity() {

    @Inject lateinit var mVehicle: Vehicle

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ComponentHolder.component.inject(this)
        
        Log.d("SecondActivity", "Vehicle speed: ${mVehicle.speed}")
    }
}