Android/Kotlin:将不同的活动“特征”组合成一个活动

The*_*PMO 7 android dependency-injection composition android-activity kotlin

我正在寻找一种在 Android 活动中组合不同功能的方法,该方法应该可用于不同的活动类。具体来说,问题是由于覆盖 open 方法而产生的,其中还必须调用 super 的实现。

open class FirstActivity : FragmentActicity() {
  override fun onStart() {
    super.onStart()
    doSomething()
  }
}
Run Code Online (Sandbox Code Playgroud)

这很简单,但它不可重复使用。例如,我可能希望使用不同的基本活动类具有相同的行为:

open class SecondActivity : AppCompatActivity() {
  override fun onStart() {
    super.onStart()
    doSomething()
  }
}
Run Code Online (Sandbox Code Playgroud)

我必须复制代码的地方。如果我有一个非常基本的功能,比如跟踪活动的状态,我会或多或少地希望在我所有具有不同基类的活动中使用它。当我想创建更多可以组合的功能时,情况会变得更糟:

open class ThirdActivity : FragmentActivity() {
  override fun onResume() {
    super.onResume()
    doSomeResuming()
  }
}

open Class FirstActivityAgain : ThirdActivity {
  override fun onStart() {
    super.onStart()
    doSomething()
  }
}

class MyFragmentActivity : FirstActivity() {
  override fun onStop() {
    doSomethingElse()
    super.onStop()
  }
}

class MyFragmentActivityWithResuming : FirstActivityAgain() {
  override fun onStop() {
    doSomethingElse()
    super.onStop()
  }
}

class MyTopBarActivity : SecondActivity() {
  override fun onStop() {
    doSomethingElse()
    super.onStop()
  }
}


Run Code Online (Sandbox Code Playgroud)

在 Scala 中,我可以使用 Traits进行这种可堆叠修改,这允许非常灵活的功能混合。甚至可以一遍又一遍地修改相同的方法,只需要注意线性化顺序。这一切在 Kotlin 中都是不可能的,因为 Scala Trait 既不等同于 Kotlin 抽象类,也不等同于 Kotlin 接口。

Kotlin 的代表似乎也不可能。我还考虑过使用泛型,在我有限的想象中它可能是这样的:

open class FirstActivity<BaseActivity : Activity> : BaseActivity() {
  ...
}
Run Code Online (Sandbox Code Playgroud)

这当然也是不可能的。

有什么我忽略的吗?可以通过使用 Dagger 来完成吗?

Pav*_*sha 0

您在 Kotlin 中所指的称为接口以及一些基本委托

interface Base {
    fun printMessage()
    fun printMessageLine()
}

class BaseImpl(val x: Int) : Base {
    override fun printMessage() { print(x) }
    override fun printMessageLine() { println(x) }
}

class Derived(b: Base) : Base by b {
    override fun printMessage() { print("abc") }
}

fun main() {
    val b = BaseImpl(10)
    Derived(b).printMessage()
    Derived(b).printMessageLine()
}
Run Code Online (Sandbox Code Playgroud)

虽然它不会让你摆脱这个super问题,因为它是 Android 框架问题而不是 Kotlin 语言问题。

对于你的情况我会做类似的事情

interface BaseActivityContainer{
 var activity: Activity
}

class MainActivity: BaseActivityContainer{

override var activity: Activity = this

}

interface BaseDoable: BaseActivityContainer{

fun doActivityStuff(){
 activity.getString(...)
}

}

interface BaseDoableSecond: BaseActivityContainer{

fun doActivityStuff(){
 activity.getDrawable(...)
}

}

class SomeActivity: MainActivity, BaseDoableSecond by this
Run Code Online (Sandbox Code Playgroud)

在 Android 生命周期的帮助下处理 Lyfecycle 事件

这并不完整,而且几乎没有功能,但我希望它能为您清除一些东西。